web-dev-qa-db-ja.com

didFinishPickingMediaWithInfoはnil写真を返します

私は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";

素晴らしいですが、画像はありません。

私はこれを行うためにこのフォーラムの優れた例を使用しており、呼び出しは正しいと確信していますが、画像ではありません。

前もって感謝します!

30
Rob Bonner

私はこれが何ヶ月も後であることを知っていますが、私は何時間もこれに苦労し、この同じ質問がこのサイトとiphonedevsdk.comの至る所で見つかりましたが、有効な答えはありませんでした。

要約すると、画像がカメラロール/写真ライブラリから選択された場合は問題なく機能しましたが、画像がカメラで撮影した新しい写真の場合は機能しませんでした。さて、これを両方で機能させる方法は次のとおりです。

UIImagePickerControllerを閉じて解放する必要がありますbefore情報ディクショナリで何でもしようとします。超明確にするために:

これは機能しません:

- (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];
}

これらのすべての場合で、イメージはnilになります。

ただし、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];
}

クレイジーシンプルですが、これですべてです。

54

マシューフレデリックの答えが最も人気があり、長い間適切な応答でしたが、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];
    }];
}
17
john.k.doe

上記のすべてを試しましたが、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]);
  }];
}
5
Alexey Suvorov

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の両方を再起動すると問題が解決するようです。

2
juanignaciosl

使用する

[[UIImagePickerController alloc] init];

の代わりに

[[UIImagePickerController alloc] initWithNibName:(NSString *) bundle:(NSBundle *)];
1
yfguo

同じ症状がありましたが、私の場合、UIImagePickerController階層の何かに「uuid」または「setUUID」を上書きするカテゴリがあることがわかりましたか? CoreDataはこれらのメソッドを必要とするか、非常に混乱します。アセットライブラリはすべてCoreDataのものです。

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

    [picker dismissViewControllerAnimated:YES completion:NULL];
    //Image picker for nil value 
    UIImage* selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
    NSLog(@"my Info :: %@", info);

    if(NULL == selectedImage){
      UIImage * selectedImage =  [PhotoViewController loadImageFromAssertByUrl:[info objectForKey:@"UIImagePickerControllerReferenceURL"]
                                     completion:^(UIImage * selectedImage){
                                         //img not null here
                                         NSLog(@"img2 ::: %@", selectedImage);
                                         uploadImg.image = selectedImage;
                                         [self.view addSubview:PermissionView];
                                     }];
    }else{
        //image not null here
        NSLog(@"Up IMG00 :: %@", uploadImg.image);
        NSLog(@"Sel IMG00 :: %@", selectedImage);
        uploadImg.image = [selectedImage retain];
        NSLog(@"Up IMG22 :: %@", uploadImg.image);
        NSLog(@"Sel IMG22 :: %@", selectedImage);

    }
}


+(UIImage *) loadImageFromAssertByUrl:(NSURL *)url completion:(void (^)(UIImage*)) completion{


    __block UIImage* img;

    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];
        img = [UIImage imageWithData:data];
        completion(img);
        NSLog(@"img ::: %@", img);
    } failureBlock:^(NSError *err) {
        NSLog(@"Error: %@",[err localizedDescription]);
    }];

    return img;
}
0
user3328172