didFinishPickingMediaWithInfo возвращает нулевое фото

Я работаю над захватом изображения, которое возвращается в 4.0, используя

- (void)imagePickerController:(UIImagePickerController *)picker 
    didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [[picker parentViewController] dismissModalViewControllerAnimated:YES]; 

    // MediaType can be kUTTypeImage or kUTTypeMovie. If it's a movie then you
    // can get the URL to the actual file itself. This example only looks for images.
    //   
    NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    // NSString* videoUrl = [info objectForKey:UIImagePickerControllerMediaURL];

    // Try getting the edited image first. If it doesn't exist then you get the
    // original image.
    //
    if (CFStringCompare((CFStringRef) mediaType,  kUTTypeImage, 0) == kCFCompareEqualTo) {               
        UIImage* picture = [info objectForKey:UIImagePickerControllerEditedImage];
        if (!picture)
            picture = [info objectForKey:UIImagePickerControllerOriginalImage];             

        // **picture is always nil
            // info dictionary count = 1


    }

}

Происходит то, что информационный словарь всегда возвращает одну запись:

{ UIImagePickerControllerMediaType = "public.image";

что здорово, но никогда нет изображения.

Я использовал отличный пример с этого форума, чтобы сделать это, и я почти уверен, что вызовы правильные, но никогда не изображение.

Заранее спасибо!


person Rob Bonner    schedule 21.06.2010    source источник
comment
Есть берущие? Огромный удар кармы на этом !!!!   -  person Rob Bonner    schedule 22.06.2010


Ответы (8)


Я знаю, что это произошло много месяцев спустя, но я часами боролся с этим и нашел этот же вопрос на всем этом сайте и на iphonedevsdk.com, но так и не получил рабочего ответа.

Подводя итог, можно сказать, что если изображение было выбрано из галереи фотографий/библиотеки фотографий, оно работало нормально, но если изображение было новой фотографией, сделанной камерой, оно никогда не работало. Ну, вот как заставить это работать для обоих:

Вы должны отклонить и освободить UIImagePickerController прежде чем пытаться что-либо сделать с информационным словарем. Чтобы быть предельно ясным:

Это НЕ работает:

- (void)imagePickerController:(UIImagePickerController *)picker 
                      didFinishPickingMediaWithInfo:(NSDictionary *)info {

          // No good with the edited image (if you allowed editing)
  myUIImageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
          // AND no good with the original image
  myUIImageView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
          // AND no doing some other kind of assignment
  UIImage *myImage = [info objectForKey:UIImagePickerControllerEditedImage];

  [picker dismissModalViewControllerAnimated:YES];
  [picker release];
}

Во всех этих случаях изображение будет нулевым.

Однако с помощью волшебства освобождения UIImagePickerController сначала...

Это ДЕЙСТВИТЕЛЬНО работает:

- (void)imagePickerController:(UIImagePickerController *)picker 
                      didFinishPickingMediaWithInfo:(NSDictionary *)info {

  [picker dismissModalViewControllerAnimated:YES];
  [picker release];

          // Edited image works great (if you allowed editing)
  myUIImageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
          // AND the original image works great
  myUIImageView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
          // AND do whatever you want with it, (NSDictionary *)info is fine now
  UIImage *myImage = [info objectForKey:UIImagePickerControllerEditedImage];
}

Безумно просто, но на этом все.

person Matthew Frederick    schedule 16.11.2010
comment
ты это серьезно!?! это то, что моя проблема была! МОЙ БОГ. _умирает_ - person Stephen Furlani; 07.01.2011
comment
Я еще не пробовал, но несколько вариантов приходят на ум как возможности. Первый — скопировать информационный словарь — NSDictionary *infoDictionary = [NSDictionary dictionaryWithDictionary:info] — и затем обнулить средство выбора — picker = nil. Не уверен, что это сработает. Другой вариант, который почти наверняка сработает, — создать отдельный файл для кода выбора изображения в Xcode и настроить этот файл так, чтобы он не использовал ARC, оставив решение здесь. - person Matthew Frederick; 23.03.2012
comment
спасибо .. У меня это работает, но наоборот. Я закрываю камеру после установки uiimage. Я не знаю, это может быть ошибка на ios. - person John Paul Manoza; 14.05.2013
comment
Ух ты. Я столкнулся с подобной проблемой, и это сделало работу. Теперь мне интересно, почему это работает? - person Chan Jing Hong; 28.12.2016

в то время как ответ Мэтью Фредерика является наиболее популярным и долгое время был подходящим ответом, начиная с iOS 5.0, Apple предоставила dismissViewControllerAnimated:completion: для замены устаревшего (начиная с iOS 6.0) dismissViewControllerAnimated:.

мы надеемся, что выполнение поиска словаря информации об изображении в блоке завершения должно иметь больше смысла для всех.

если взять его пример сверху, теперь это будет выглядеть так:

- (void)    imagePickerController:(UIImagePickerController *)picker 
    didFinishPickingMediaWithInfo:(NSDictionary *)info 
{
    [picker dismissViewControllerAnimated:YES completion:^{
          // Edited image works great (if you allowed editing)
        myUIImageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
          // AND the original image works great
        myUIImageView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
          // AND do whatever you want with it, (NSDictionary *)info is fine now
        UIImage *myImage = [info objectForKey:UIImagePickerControllerEditedImage];
    }];
}
person john.k.doe    schedule 30.11.2012
comment
Вы уверены, что это [picker dismissModalViewControllerAnimated:YES completion:, а не [picker dismissViewControllerAnimated:YES completion:^(void)? - person James Dunay; 31.08.2013
comment
Это по-прежнему дает нулевой результат для меня, запуская приложение для iPhone в эмуляторе iPad (iOS 6.1). - person Desty; 06.09.2013
comment
На самом деле кажется, что это давняя ошибка в эмуляторе iPad, начиная с iOS 5, хотя, похоже, она работает на реальном устройстве. Странный. Таким образом, единственным решением является использование библиотеки активов... - person Desty; 06.09.2013

Я пробовал все вышеперечисленное, но не повезло с симулятором iPad 6.0/6.1, однако я обнаружил, что информация содержит ключ «UIImagePickerControllerReferenceURL», и вот мой код:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
  [picker dismissViewControllerAnimated:YES completion:NULL];

  UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
  if(NULL == image){
      [MyImageLoader loadImageFromAssertByUrl:[info objectForKey:@"UIImagePickerControllerReferenceURL"]
                                   completion:^(UIImage* img){
                                        //img not null here
                                   }];
  }else{
      //image not null here
  }
}

и код для loadImageFromAssertByUrl:

+(void) loadImageFromAssertByUrl:(NSURL *)url completion:(void (^)(UIImage*)) completion{
  ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
  [assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) {
      ALAssetRepresentation *rep = [asset defaultRepresentation];
      Byte *buffer = (Byte*)malloc(rep.size);
      NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
      NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
      UIImage* img = [UIImage imageWithData:data];
      completion(img);
  } failureBlock:^(NSError *err) {
      NSLog(@"Error: %@",[err localizedDescription]);
  }];
}
person Alexey Suvorov    schedule 14.08.2013
comment
Спасибо! Я не могу поверить, что нам нужно делать такие вещи, чтобы обойти ошибку в эмуляторе iPad, о которой сообщалось по крайней мере год назад, но, по крайней мере, ее можно обойти... - person Desty; 06.09.2013

Также есть известная ошибка с некоторыми версиями XCode и Mountain Lion. Проверьте консоль на наличие этого сообщения:

2013-01-17 21:36:34.946 3sure-ios[5341:1803] Named service 'com.apple.PersistentURLTranslator.Gatekeeper' not found. assetsd is down or misconfigured. Things will not work the way you expect them to.

Вероятно, это не сработает, если появится это сообщение. Проверьте свое приложение на реальном устройстве iOS.

Тем не менее, перезапуск симулятора и XCode, похоже, решает проблему.

person juanignaciosl    schedule 17.01.2013
comment
Я не видел этой ошибки, но на симуляторе изображение пустое, на устройстве оно работает... - person Justin Meiners; 19.02.2013

использовать

[[UIImagePickerController alloc] init];

вместо

[[UIImagePickerController alloc] initWithNibName:(NSString *) bundle:(NSBundle *)];
person yfguo    schedule 25.01.2013

У меня были те же симптомы, но в моем случае оказалось, что у меня есть категория для чего-то в иерархии UIImagePickerController, которая переопределяет «uuid» или «setUUID»? Я предполагаю, что CoreData нуждается в этих методах, иначе он будет очень, очень запутан, а библиотека активов - это все, что нужно CoreData.

person Mason Cloud    schedule 05.04.2012

Необходимо выполнить следующие шаги:
1) Сделать UIActionSheet
2) При выборе необходимого типа источника - загрузить ресурсы
3) didFinishPickingMediaWithInfo - установить изображение из полученного словаря изображения

    - (IBAction)actionButtonUpload:(id)sender {

             UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self 

cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Camera",@"Photo Library", nil];

         [actionSheet showInView:self.view];

    }

    #pragma mark -- UIActionSheet Delegate
    -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{

        UIImagePickerController *picker = [[UIImagePickerController alloc] init];

        picker.delegate = self;
        picker.allowsEditing = YES;
        UIAlertView *alert;


        switch (buttonIndex) {
            case 0:
                if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {

                    NSLog(@"No camera!");
                    picker.sourceType = UIImagePickerControllerSourceTypeCamera;
                    [self presentViewController:picker animated:YES completion:NULL];


                } else {

                    alert = [[UIAlertView alloc]initWithTitle:@"Alumnikonnect" message:@"Camera is not available, please select a different media" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];

                    [alert show];

                }
                break;
            case 1:

                if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {

                    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
                    [self presentViewController:picker animated:YES completion:NULL];


                } else {

                    alert = [[UIAlertView alloc]initWithTitle:@"Alumnikonnect" message:@"Photolibrary is not available, please select a different media" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];

                    [alert show];

                }

                break;

        }

    }


    #pragma mark - Image picker delegate

    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
          self.imageEventPic.layer.cornerRadius =   self.imageEventPic.frame.size.height /2;
          self.imageEventPic.layer.masksToBounds = YES;
          self.imageEventPic.layer.borderWidth = 0;
          self.imageEventPic.layer.borderWidth = 1.0f;
          self.imageEventPic.layer.borderColor = [UIColor colorWithRed:0.212 green:0.255 blue:0.302 alpha:1.000].CGColor;


        self.labelUploadPic.hidden = YES;

        self.imageEventPic.image =  info[UIImagePickerControllerOriginalImage];

        [self dismissViewControllerAnimated:YES completion:NULL];

    }


    - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
    {
        [self dismissViewControllerAnimated:YES completion:NULL];

    }

    -(UIImage*)imageWithImage:(UIImage*)image
                 scaledToSize:(CGSize)newSize;
    {
        UIGraphicsBeginImageContext( newSize );

        [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];

        UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();

        UIGraphicsEndImageContext();

        return newImage;

    }
person bhavya kothari    schedule 16.06.2014

person    schedule
comment
У меня была такая же проблема в iPad air и iOS 8, и я решил свою проблему с помощью этих кодов. Спасибо. - person dobiho; 21.10.2014