通过 PHAsset 获取图片遇到的坑
2017-06-08 本文已影响1183人
CoderHG
从 iOS 8 以后相册的资源对象变成了 PHAsset,现在来简单介绍一下在使用 PHAsset 的过程中遇到的坑.
原本用的方法是:
/**
通过资源获取图片的数据
@param mAsset 资源文件
@param imageBlock 图片数据回传
*/
- (void)fetchImageWithAsset:(PHAsset*)mAsset imageBlock:(void(^)(NSData*))imageBlock {
[[PHImageManager defaultManager] requestImageForAsset:mAsset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:nil resultHandler:^(UIImage *resultImage, NSDictionary *info) {
if ([[info valueForKey:@"PHImageResultIsDegradedKey"]integerValue] == 0){
// 这里获取的 resultImage 的确是原图
// 所以需要将 resultImage 转成 NSData 类型的
// 方案一
NSData* imageData = UIImagePNGRepresentation(resultImage);
{ // 方案二
imageData = UIImageJPEGRepresentation(resultImage, 1.0);
}
// 通过 imageBlock 返回
if (imageBlock) {
imageBlock(imageData);
}
}
}];
}
看这代码,没毛病。但是,实际上有很大的毛病,并且不容易被发现。
上传到服务器的图片那时相当的大,我有一张1.3M的图片,上传之后变成了9.3M了。厉害了,我的锅!!!!!就是从 UIImage 转 NSData 的那一步出了猫腻,不管是 方案一 还是 方案二。
遇到这样的情况,实在让人着急。一看 QQ 的图片上传,没有毛病。看来是自己的问题了。。。。。
最终,找到了如下方法:
/**
通过资源获取图片的数据
@param mAsset 资源文件
@param imageBlock 图片数据回传
*/
- (void)fetchImageWithAsset:(PHAsset*)mAsset imageBlock:(void(^)(NSData*))imageBlock {
[[PHImageManager defaultManager] requestImageDataForAsset:mAsset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
// 直接得到最终的 NSData 数据
if (imageBlock) {
imageBlock(imageData);
}
}];
}
终于可以缓一口气了,经测试也木有毛病,上传到服务器的大小完全匹配。
什么情况?????? 又出问题了。。。。。
有的图片被旋转了,赶紧改!!!!厉害了,还是我的锅。。。
图片旋转的原因,在网上有一些说法。但是我发现通过 PHPhotoLibrary 保存到相册的方式,会发生旋转的概率是百分之百。
经过一番的折腾,找到了这个iPhone上关于相机拍照的图片的imageOrientation的问题,于是灵机一动,就写成下面的方法,我也是尽力了。
/**
通过资源获取图片的数据
@param mAsset 资源文件
@param imageBlock 图片数据回传
*/
- (void)fetchImageWithAsset:(PHAsset*)mAsset imageBlock:(void(^)(NSData*))imageBlock {
[[PHImageManager defaultManager] requestImageDataForAsset:mAsset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
if (orientation != UIImageOrientationUp) {
UIImage* image = [UIImage imageWithData:imageData];
// 尽然弯了,那就板正一下
image = [image fixOrientation];
// 新的 数据信息 (不准确的)
imageData = UIImageJPEGRepresentation(image, 0.5);
}
// 直接得到最终的 NSData 数据
if (imageBlock) {
imageBlock(imageData);
}
}];
}
到这里,也就算是结束了。但是,关于 图片被旋转了 的这个问题,还是没有完全被解决,因为通过 UIImageJPEGRepresentation 处理过的数据是未知的。个人感觉要彻底解决这个问题,应该是要手动的去篡改 imageOrientation 这个值了, 但是我不会。要是有大神知道更好的解决方案,期待你的分享。