保存后获取与PHAsset相同的NSData

Posted

技术标签:

【中文标题】保存后获取与PHAsset相同的NSData【英文标题】:Get the same NSData of PHAsset after save 【发布时间】:2018-11-19 11:58:34 【问题描述】:

您知道在使用phphotoLibrary 保存后是否有任何方法可以获取相同的图像 NSData(JPG、PNG)?

OfC,ios 将在保存后修改一些元数据和EXIF-->(时间戳,...)数据,但是,我询问的是 UIImage 数据(包括相同的 EXIF 数据)。 我没有在我的代码中复制 exif,但它不起作用 所以让我们谈谈代码:

保存图片并获取哈希

 UIImage * tmp = [[UIImage alloc] initWithData:tmpData];
 tmpData =UIImageJPEGRepresentation(tmp, 1.0);
 self.str1 =  [tmpData MD5];                
 [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^
 PHAssetResourceCreationOptions *options = [[PHAssetResourceCreationOptions alloc] init];
 options.originalFilename = @"XXX";
 PHAssetCreationRequest * createReq   =   [PHAssetCreationRequest creationRequestForAsset];
[createReq  addResourceWithType:PHAssetResourceTypePhoto data:tmpData options:options];
             completionHandler:^(BOOL success, NSError * _Nullable error) 
    NSLog(@":%d",success);
 ];

加载相同的图像:

[asset requestContentEditingInputWithOptions:0 completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput,  NSDictionary * _Nonnull info) 
 PHImageRequestOptions * option = [[PHImageRequestOptions alloc] init];
 option.synchronous = YES;
 option.version = PHImageRequestOptionsVersionOriginal;
 option.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
 option.resizeMode = PHImageRequestOptionsResizeModeNone;
 [[PHImageManager defaultManager] requestImageDataForAsset:asset options:option resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) 


 UIImage * image = [UIImage imageWithData:imageData];
 NSData * tmpDAt =  UIImageJPEGRepresentation(image, 1.0);           
 NSString * md5 =  [tmpDAt MD5];
 if ([md5 isEqualToString:self.str1]) 
  NSLog(@"My Expextation");
     
];

我发现有趣的是,如果我将图像裁剪为1*1 进行测试,我会在保存过程中收到一些错误(JPEGDecompressSurface : Picture decode failed:)(似乎操作系统无法修改图像)所以我之前得到了相同的哈希值保存后:)!

【问题讨论】:

【参考方案1】:

我认为差异是由于您的 JPEG 在其 EXIF 元数据中具有不同的时间戳(可能还有其他差异)。

您是否尝试过使用UIImagePNGRepresentation 而不是UIImageJPEGRepresentation?希望 PNG 表示会匹配。

【讨论】:

我也在考虑这个问题,但是如果我为新图像复制所有 EXIF 数据怎么办? (JPEG) 另外,我也尝试使用UIImagePNGRepresentation,因为您知道 PNG 不会保持方向,所以我检查了所有方向的 md5 结果,并且与原始结果不匹配。我认为它可能与时间戳和......但不确定,因为我正在复制新图像的所有 EXIF 信息【参考方案2】:

Jpeg 压缩是一种有损压缩形式。每次转换为 Jpeg 时都会丢失数据。没有其他办法了。从方程中删除 PHPhotoLibrary。如果你运行以下

UIImage * tmp = [[UIImage alloc] initWithData:tmpData];
tmpData =UIImageJPEGRepresentation(tmp, 1.0);
str1 =  [tmpData MD5];
tmp = [[UIImage alloc] initWithData:tmpData];
tmpData =UIImageJPEGRepresentation(tmp, 1.0);
str2 =  [tmpData MD5];

你会发现str1和str2是不一样的。

如果您想要相同的数据,则必须保留生成图像的原始 jpeg 数据或使用无损压缩方法,如 PNG 文件中使用的方法。

【讨论】:

以上是关于保存后获取与PHAsset相同的NSData的主要内容,如果未能解决你的问题,请参考以下文章

如何从 PHAsset 获取图像 URL?是不是可以使用 PHAsset URL 将图像保存到文档目录?

获取保存到照片库的图像的 PHAsset/localIdentifier

在核心数据中保存 PHAsset?

如何使用 fetchAssetsWithALAssetURLs 获取 PHAsset

应用程序在 swift 中为所有视频 PHAsset 播放相同的视频

PHAsset,如何在应用重启后检索特定的 PHAsset 对象(ios8 Photos)