美文网首页图片iOS DeveloperiOS学习笔记
通过 PHAsset 获取图片遇到的坑

通过 PHAsset 获取图片遇到的坑

作者: CoderHG | 来源:发表于2017-06-08 20:37 被阅读1183次

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了。厉害了,我的锅!!!!!就是从 UIImageNSData 的那一步出了猫腻,不管是 方案一 还是 方案二

遇到这样的情况,实在让人着急。一看 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 这个值了, 但是我不会。要是有大神知道更好的解决方案,期待你的分享。

相关文章

  • 通过 PHAsset 获取图片遇到的坑

    从 iOS 8 以后相册的资源对象变成了 PHAsset,现在来简单介绍一下在使用 PHAsset 的过程中遇到的...

  • Photos.framework

    ​通过PHAsset获取本地相册图片,主要通过PHImageManager获取.获取图片有两个接口,分别获取UII...

  • 多张图片转视频

    这里传入的是 PHAsset *expAsset然后我处理,获取到image 数组通过图片数组 来搞 用到XPFF...

  • iOS开发 PHAsset使用

    用PHAsset获取照片名称目前网上有三种方法。 第一种: 这种方法是通过获取图片的URL路径,然后再获取图片名称...

  • 自定义图片选择器iOS

    基于PHAsset封装的图片选择浏览器:1.获取所有图片资源信息: 2.根据图片资源信息获取图片: 3.设置图片选...

  • iOS 用PHAsset获取照片名

    用PHAsset获取手机相册照片名称目前网上有三种方法。 第一种: 这种方法是通过获取图片的URL路径,然后再获取...

  • Photos框架获取本地图片视频信息

    1.PHAsset获取本地图片的信息:名称,大小 2.对于拍照 获取本地图片的信息:名称,大小 YMImage分类...

  • PhotoKit获取资源大小

    使用PHAsset来获取图像以及视频文件的大小 对于图片资源 对于视频资源

  • PHAsset:拍照完获取PHAsset对象

    发布朋友圈项目遇到:拍照完需获取PHAsset对象 解决方案: 将拍下的相片保存到相册,再从相册读取PHAsset...

  • 2021-09-01

    iOS获取PHAsset的图片或视频资源的本地地址URL 项目中,之前使用UIImagePickerControl...

网友评论

  • 不知蜕变的挣扎:[[PHImageManager defaultManager] requestImageDataForAsset 获取的imageData确实才1M多,但是用这个imageData转为图片 就变成6M多了,请问这是为什么?要如何转换成1M多的图片?
  • 拔山河:完美解决方案见我的新文章《通过PHAsset获取的图片上传后变大和图像被旋转90度问题完美解决方案》https://blog.csdn.net/jia12216/article/details/82148982(通过新建立相同的localIdentifier的PHAsset来实现获取到的图片和原图片大小相同,方向正常。)。完美和你只隔一层纸。
  • astring:fixOrientation 呢?老铁
    astring:@CoderHG 谢谢,好像iOS11也可以用ALAsset呀
    CoderHG:@astring 这个方法也是在网上直接 copy 的,之前使用感觉还是不错的。
    CoderHG:代码太长,不能再评论中回复,在文章中补充了。:blush:

本文标题:通过 PHAsset 获取图片遇到的坑

本文链接:https://www.haomeiwen.com/subject/bnvtqxtx.html