metadata - 从UIImagePickerControlleHow的结果中,如何获取包含元数据的JPEG?

标签 metadata uiimagepickercontroller jpeg uiimagejpegrepresentation

在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";
}

使用这些键中的一个或多个,如何获得包含图像元数据(例如曝光信息和GPS位置数据)的JPEG表示,以便可以将其上载到某个位置并包含元数据(不剥离)?

我从Warren Burton在Display image from URL retrieved from ALAsset in iPhone?中给出的非常好的答案中看到了如何使用UIImagePickerControllerReferenceURL和ALAssetsLibrary assetForURL方法来获取ALAsset和ALAssetRepresentation。但是,我该怎么办才能获取其中包含所有元数据的JPEG?

还是通过UIImage有一种机制?

最重要的是,我想获取其中包含元数据的JPEG ...

最佳答案

自从我问了这个问题以来,我做了更多的实验,并认为我现在知道答案了。所有结果都是在iOS 4.2上获得的,这是我关心的全部...

首先,我们使用了UIImageJPEGRepresentation ala:

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

这似乎并不能给您(大部分)图像中的元数据(EXIF,GPS等)。足够公平,我认为这是众所周知的。

我的测试表明,图像 Assets 的“默认表示形式”中的JPEG将包含所有元数据,包括EXIF和GPS信息(假设它位于第一位)。通过从 Assets URL到 Assets 到 Assets 的默认表示形式(ALAssetRepresentation),然后使用getBytes方法/消息检索JPEG图像的字节,可以获取该图像。该字节流中包含上述元数据。

这是我用于此的一些示例代码。它采用一个 Assets 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];
}

关于metadata - 从UIImagePickerControlleHow的结果中,如何获取包含元数据的JPEG?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5173764/

相关文章:

ios - 如何在 UIImagePickerController 类型视频模式下拍照

c++ - 将 BGR 图像转换为 base64 字符串作为 jpeg

Delphi - 加载 JPEG 并将输出打印为黑色方 block ?

windows - Git for Windows - 防止 .pack 文件日期/时间修改

用于对 WordPress 用户元数据进行排序的 MYSQL 查询

objective-c - iOS:使用相机时放大到屏幕的一部分

导航 View Controller 中的 IOS 图像选择器

php - 在 Yii2 中获取模型属性的类型

php - 在 s3 分段上传上设置内容类型元数据

android - 快速解码 JPEG 图像的方法