5

iOS 4.2で、UIImagePickerControllerを使用してユーザーがフォトライブラリから画像を選択できるようにすると、次の辞書キーが返されます。

2011-03-02 13:15:59.518 xxx[15098:307] didFinishPickingMediaWithInfo: 
  info dictionary: {
    UIImagePickerControllerMediaType = "public.image";
    UIImagePickerControllerOriginalImage = "<UIImage: 0x3405d0>";
    UIImagePickerControllerReferenceURL = 
      "assets-library://asset/asset.JPG?id=1000000050&ext=JPG";
}

これらのキーの1つ以上を使用して、画像メタデータ(露出情報やGPS位置データなど)を含むJPEG表現を取得して、どこかにアップロードし、メタデータを含める(削除しない)にはどうすればよいですか?

iPhoneのALAssetから取得したURLからの画像の表示で、ウォーレンバートンの非常に良い答えがわかりますか?UIImagePickerControllerReferenceURLおよびALAssetsLibraryassetForURLメソッドを使用してALAssetおよびALAssetRepresentationにアクセスする方法。しかし、すべてのメタデータを含むJPEGに到達するには、どうすればよいでしょうか。

または、UIImageを介したメカニズムはありますか?

ここで重要なのは、メタデータが含まれているJPEGを取得したいということです...

4

1 に答える 1

7

この質問をして以来、さらに実験を行った結果、答えがわかったと思います。すべての結果は iOS 4.2 で得られたもので、私が気にかけているのは...

まず、UIImageJPEGRepresentationalaを使用していました。

NSData *imageData = UIImageJPEGRepresentation(self.selectedImage, 0.9);

これは、画像に含まれるメタデータ (EXIF、GPS など) を (ほとんど) 提供していないようです。十分に公平であり、それはよく知られていると思います。

私のテストでは、画像アセットの「デフォルト表現」の JPEG には、EXIF および GPS 情報を含むすべてのメタデータが含まれることが示されています (最初にそこにあると仮定します)。アセット URL からアセット、アセットのデフォルト表現 (ALAssetRepresentation) に移動し、getBytes メソッド/メッセージを使用して JPEG 画像のバイトを取得することで、その画像を取得できます。そのバイト ストリームには、前述のメタデータが含まれています。

これに使用するサンプルコードを次に示します。画像用であると推定されるアセット URL を受け取り、JPEG を含む NSData を返します。使用上の注意、コード内のエラー処理など

/*
 * Example invocation assuming that info is the dictionary returned by 
 * didFinishPickingMediaWithInfo (see original SO question where
 * UIImagePickerControllerReferenceURL = "assets-library://asset/asset.JPG?id=1000000050&ext=JPG").
 */
[self getJPEGFromAssetForURL:[info objectForKey:UIImagePickerControllerReferenceURL]];
// ...

/* 
 * Take Asset URL and set imageJPEG property to NSData containing the
 * associated JPEG, including the metadata we're after.
 */
-(void)getJPEGFromAssetForURL:(NSURL *)url {
    ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
    [assetslibrary assetForURL:url
        resultBlock: ^(ALAsset *myasset) {
            ALAssetRepresentation *rep = [myasset defaultRepresentation];
#if DEBUG
            NSLog(@"getJPEGFromAssetForURL: default asset representation for %@: uti: %@ size: %lld url: %@ orientation: %d scale: %f metadata: %@", 
            url, [rep UTI], [rep size], [rep url], [rep orientation], 
            [rep scale], [rep metadata]);
#endif

            Byte *buf = malloc([rep size]);  // will be freed automatically when associated NSData is deallocated
            NSError *err = nil;
            NSUInteger bytes = [rep getBytes:buf fromOffset:0LL 
                                length:[rep size] error:&err];
            if (err || bytes == 0) {
                // Are err and bytes == 0 redundant? Doc says 0 return means 
                // error occurred which presumably means NSError is returned.

                NSLog(@"error from getBytes: %@", err);
                self.imageJPEG = nil;
                return;
            } 
            self.imageJPEG = [NSData dataWithBytesNoCopy:buf length:[rep size] 
                                     freeWhenDone:YES];  // YES means free malloc'ed buf that backs this when deallocated
        }
        failureBlock: ^(NSError *err) {
            NSLog(@"can't get asset %@: %@", url, err);
        }];
    [assetslibrary release];
}
于 2011-03-04T08:21:36.550 に答える