iOS 11 HEIF/HEIC图片转JPG、UIImage加载

作者: 知傲 | 来源:发表于2017-10-14 16:15 被阅读3441次

iOS 11中,如果你是iPhone 7及以上设备,系统用了新的格式来存储视频和图片,



如果你的App支持上传图片原文件,那么很可能会有图片无法显示的问题。
读取图片原文件的代码一般是下面这样的,传到后台之后得到一个url,webview和UIImage是无法显示的。

[[PHImageManager defaultManager] requestImageDataForAsset:phAsset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
    if (imageData) {
        
    }
}];

当我们讲适配的时候,往往比较多地关注UI的适配,容易忽略一些看不见的东西。

识别HEIF

识别HEIF文件的方法和识别GIF一样,对比文件UTI(uniformTypeIdentifier)

__block BOOL isHEIF = NO;
if (iOSVersionGreaterThanOrEqualTo(@"9.0")) {
    NSArray *resourceList = [PHAssetResource assetResourcesForAsset:phAsset];
    [resourceList enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        PHAssetResource *resource = obj;
        NSString *UTI = resource.uniformTypeIdentifier;
        if ([UTI isEqualToString:@"public.heif"] || [UTI isEqualToString:@"public.heic"]) {
            isHEIF = YES;
            *stop = YES;
        }
    }];
} else {
    NSString *UTI = [phAsset valueForKey:@"uniformTypeIdentifier"];
    isHEIF = [UTI isEqualToString:@"public.heif"] || [UTI isEqualToString:@"public.heic"];
}

下面这个方法不准确

[[PHImageManager defaultManager] requestImageDataForAsset:phAsset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
    //这个dataUTI只是根据文件扩展名传过来的,不准确
}];

转换

方法一:有损

既然我们可以前置识别了,那么针对HEIF可以选择通过requestImageDataForAsset:phAsset获取到UIImage,再用UIImageJPEGRepresentation转为NSData,不过转为UIImage之后,图片的其他信息(Exif、GPS等)就丢失了。

方法二:无损
[[PHImageManager defaultManager] requestImageDataForAsset:phAsset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
    if (isHEIF) {
        CIImage *ciImage = [CIImage imageWithData:imageData];
        CIContext *context = [CIContext context];
        NSData *jpgData = [context JPEGRepresentationOfImage:ciImage colorSpace:ciImage.colorSpace options:@{}];
    } else {
    }
}];
方法三:无损
if (isHEIF) {
    [phAsset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
        if (contentEditingInput.fullSizeImageURL) {
            CIImage *ciImage = [CIImage imageWithContentsOfURL:contentEditingInput.fullSizeImageURL];
            CIContext *context = [CIContext context];
            NSData *jpgData = [context JPEGRepresentationOfImage:ciImage colorSpace:ciImage.colorSpace options:@{}];
        }
    }];
}

UIImage加载HEIF

CIImage *ciImage = [CIImage imageWithContentsOfURL:url];
imageView.image = [UIImage imageWithCIImage:ciImage];

这个方法有点慢,也可以使用CGImageSourceCreateWithURL和CGImageSourceCreateImageAtIndex加载

相关文章

网友评论

  • cb426020b395:为什么图片的方向不对呢?图片的方向显示的还是向上,但是显示的却是向下或者向左之类的
  • August24:博主,转化jpeg的方法中option 传入参数
    NSString *key = (__bridge NSString *)kCGImageDestinationLossyCompressionQuality;
    NSData *jpgData = [context JPEGRepresentationOfImage:ciImage colorSpace:ciImage.colorSpace options:@{key: @1}];
    可获取jpeg原图data
  • 开发者头条_程序员必装的App:感谢分享!已推荐到《开发者头条》:https://toutiao.io/posts/j8x0mn 欢迎点赞支持!
  • da27c260cc85:如何产生heif的图片呢?
  • 流火绯瞳:这样转换之后数据量会恢复到实际的大小, 有没有方法使后台能够转换这种格式呢? 毕竟这种格式传输时, 数据量会小很多. 7p拍的照片, 未转化前不到1M, 转换后就恢复到十几M了
    August24:@流火绯瞳 可不是嘛,博主写的也是转成jpeg的data啊
    流火绯瞳:@August24 通过微信发送,会被转为jpg格式
    August24:这样才是原图的大小。你可以拿微信发一下试一下
  • 流火绯瞳:学习了, 最近正在找这个问题的解决方法:+1:
  • 213cd098169c:iphone7plus,系统是ios11,设置拍照格式也是heif,从airDrop传出来的照片怎么都是jpg的格式呢
    知傲:@billy_9527 设置-照片-最底下 传输到Mac或PC 选保留原始照片
    213cd098169c:@zhao0 请问这个导出怎么设置
    知傲:@billy_9527 还有一个导出的选项,应该是设了兼容模式
  • 213cd098169c:请问怎么可以弄成heif格式的图片
    流火绯瞳:func toHEIC(_ data: Data) -> Data? {
    let ciImage = CIImage(data: data)
    guard let image = ciImage else {
    return nil
    }

    let context = CIContext()
    let heicData = context.heifRepresentation(of: image, format: kCIFormatABGR8, colorSpace: image.colorSpace!, options: [:])
    return heicData
    }
    这是系统提供的方法, 你可以试下

本文标题:iOS 11 HEIF/HEIC图片转JPG、UIImage加载

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