iOS不支持HEIC格式的图片显示和标签函数显示问题及解决方案

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: iOS不支持HEIC格式的图片显示和标签函数显示问题及解决方案

iOS不支持HEIC格式图片解决方案:在阿里云的图片下载规则里配置为把WebP格式图片转换成png或 jpeg格式的图片。从根源解决是当上传这种格式图片时,以文件名后缀识别出这种格式的图片,然后把它转换成png或 jpeg格式的图片再上传。

HEIC可是连iphone4,5,6都不支持的图片格式,不知道苹果为何推出连自己的产品都不完全支持的图片格式干什么,徒给我们码农添麻烦。看来支持万能格式的图片上传也是有罪的。想法是美好的,现实是骨感的。


HEIC是iOS 11更新后,iPhone 7及其后硬件,在拍摄照片时的默认图像存储格式。

HEIC是一种图像格式,上线时间还比较短,只有4年左右。自iOS 11和macOS High Sierra(10.13)内测开始,苹果将HEIC设置为图片存储的默认格式。

与JPG相比,它占用的空间更小,画质更加无损。

HEIC格式照片支持iOS11及macOS High Sierra(10.13)及更新版本。

但是此种格式是无法在Windows 中直接使用看图软件打开的(Windows10 RS4开始支持该格式)。

所以如果想要在电脑中查看HEIC图片,最好使用在线免费HEIC图片转换应用,将HEIC转JPG,这样就可以在PC上打开iPhone HEIC照片了。

想推出一种流行的像png或 jpeg一样的图像压缩格式是很不容易的。

HEIC格式一张图片。

安卓可以产生WebP这种格式的图片,微信网页不支持这种格式图片,苹果手机也不支持这种格式的图片,但是安卓支持。HEIC图片也有类似的尴尬。

下面是上传图片时,发现是不支持格式的图片(除PNG, BMP,GIF,JPG,JPEG常规格式以外的图片),就把它转化为png格式的图片再上传。为何不使用JPEG格式,因为JPEG不支持透明背景,而WebP和都HEIC都支持透明背景。

-(NSString *)getFileExtend:(NSString *)localId
                secondFlag:(BOOL)secondFlag
{
    NSString *urlStr = localId;
    NSLog(@"localId = %@",localId);
    if(!([urlStr containsString:@"yxLocalFile://"] || [urlStr containsString:@"yxlocalfile://"])) {
        return nil;
    }
    NSArray* arr = [urlStr componentsSeparatedByString:@"yxLocalFile://"];
    NSArray* arr2 = [urlStr componentsSeparatedByString:@"yxlocalfile://"];
    if((arr.count <= 1) && (arr2.count <= 1))
    {
        return nil;
    }
    else
    {
        if(arr.count == 1)
        {
            arr = arr2;
        }
        NSString *yxLocalFile = arr[arr.count - 1];
        NSArray* jpgArr = [yxLocalFile componentsSeparatedByString:@"."];
        if(jpgArr.count <= 1)
        {
            return nil;
        }
        else if((jpgArr.count > 2) && secondFlag)
        {
            NSString *fileExtend = jpgArr[jpgArr.count-2];
            if(isEmptyString(fileExtend))
            {
                return nil;
            }
            return [fileExtend uppercaseString];
        }
        else
        {
            NSString *fileExtend = jpgArr[jpgArr.count-1];
            if(isEmptyString(fileExtend))
            {
                return nil;
            }
            return [fileExtend uppercaseString];
        }
    }
}

//检查图片的后缀是否是支持图片格式
-(BOOL)checkImageFileExtend
{
    if(isEmptyString(self))
    {
        return YES;
    }
    NSString *fileExtend = [self uppercaseString];
    //https://image.oss.m.1-joy.com/2018-09-19/6578b5b7ae171f0d8dcbd628e1bfc6fb.HEIC?x-oss-process=style/wxlookup
    NSArray* fileExtendArr = [fileExtend componentsSeparatedByString:@"?"];
    if(fileExtendArr.count > 1)
    {
        fileExtend = fileExtendArr[0];
    }
    if([fileExtend isEqualToString:@"PNG"] || [fileExtend isEqualToString:@"BMP"] || [fileExtend isEqualToString:@"GIF"] || [fileExtend isEqualToString:@"JPG"] || [fileExtend isEqualToString:@"JPEG"])
    {
        return YES;
    }
    return NO;
}

//使用的代码片段
            NSString *fileExtend = [self getFileExtend:localId secondFlag:YES];
            if(![fileExtend checkImageFileExtend])
            {
                UIImage* image = [self compressImageWithDada:imageData];
                imageData = UIImagePNGRepresentation(image);
                fileExtend = [self getFileExtend:localId secondFlag:NO];
            }

对标签函数预加载图片的处理,在HybridNSURLProtocol.m文件里完成,发现是不支持格式的图片(除PNG, BMP,GIF,JPG,JPEG常规格式意外的图片),就把它转化为png格式的图片显示:

-(NSString *)getFileExtend:(NSString *)localId
{
    NSString *urlStr = localId;
    NSLog(@"localId = %@",localId);
    if(!([urlStr containsString:@"yxLocalFile://"] || [urlStr containsString:@"yxlocalfile://"])) {
        return nil;
    }
    NSArray* arr = [urlStr componentsSeparatedByString:@"yxLocalFile://"];
    NSArray* arr2 = [urlStr componentsSeparatedByString:@"yxlocalfile://"];
    if((arr.count <= 1) && (arr2.count <= 1))
    {
        return nil;
    }
    else
    {
        if(arr.count == 1)
        {
            arr = arr2;
        }
        NSString *yxLocalFile = arr[arr.count - 1];
        NSArray* jpgArr = [yxLocalFile componentsSeparatedByString:@"."];
        if(jpgArr.count <= 1)
        {
            return nil;
        }
        else if(jpgArr.count > 2)
        {
            NSString *fileExtend = jpgArr[jpgArr.count-2];
            if(isEmptyString(fileExtend))
            {
                return nil;
            }
            return [fileExtend uppercaseString];
        }
        else
        {
            NSString *fileExtend = jpgArr[jpgArr.count-1];
            if(isEmptyString(fileExtend))
            {
                return nil;
            }
            return [fileExtend uppercaseString];
        }
    }
}


- (void)startLoading
{
    NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
    //给我们处理过的请求设置一个标识符, 防止无限循环,
    [NSURLProtocol setProperty:@YES forKey:KHybridNSURLProtocolHKey inRequest:mutableReqeust];
    
    NSString *urlStr = mutableReqeust.URL.absoluteString;
    NSLog(@"mutableReqeust.URL.absoluteString = %@",urlStr);
    NSLog(@"请求方式 == %@",mutableReqeust.HTTPMethod);
    NSString *fileName = [self getYxLocalFile:urlStr];
    if(!isEmptyString(fileName))
    {
        NSString *MIMETypeStr = @"";
        NSString *fileExtend = [self getFileExtend:urlStr];
        if(fileExtend && ([fileExtend compare:@"png" options:NSCaseInsensitiveSearch |NSNumericSearch] ==NSOrderedSame))
        {
            MIMETypeStr =@"image/png";
        }
        else if(fileExtend && (([fileExtend compare:@"bmp" options:NSCaseInsensitiveSearch |NSNumericSearch] ==NSOrderedSame)
                               || ([fileExtend compare:@"gif" options:NSCaseInsensitiveSearch |NSNumericSearch] ==NSOrderedSame)))
        {
            //bmp\dib
            MIMETypeStr =@"image/bmp";
        }
        else if(fileExtend && ([fileExtend compare:@"gif" options:NSCaseInsensitiveSearch |NSNumericSearch] ==NSOrderedSame))
        {
            MIMETypeStr =@"image/gif";
        }
        else
        {
            //苹果拍照的图片都是JPG格式的图片,jpe\jpeg\jpg
            MIMETypeStr =@"image/jpeg";
        }
        NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[mutableReqeust URL]
                                             MIMEType:MIMETypeStr
                                expectedContentLength:-1
                                     textEncodingName:nil];
        
        NSMutableArray *tempArr = [NSMutableArray array];
        [tempArr addSafeObject:fileName];
        PHFetchResult *fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:tempArr options:nil];
        @weakify(self);
        [self fetchImageWithAsset:fetchResult.firstObject imageBlock:^(NSData *imageData) {
            @strongify(self);
            NSString *fileExtend = [self getFileExtend:urlStr];
            if(![fileExtend checkImageFileExtend])
            {
                UIImage* image = [UIImage imageWithData:imageData];
                imageData = UIImagePNGRepresentation(image);
            }
            else
            {
                UIImage *image = [UIImage imageWithData:imageData];
                if((maxShareImageWidth > 0) && (maxShareImageHeight > 0) && ((image.size.height > maxShareImageHeight) || (image.size.width > maxShareImageWidth)))
                {
                    UIImage* newImage = [self compressImageWithImage:image];
                    imageData = UIImageJPEGRepresentation(newImage, 0.7);
                    fileExtend = @"JPG";
                }
            }
            NSLog(@"imageData:%@", imageData);
            [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
            [[self client] URLProtocol:self didLoadData:imageData];
            [[self client] URLProtocolDidFinishLoading:self];
        }];

        return;
    }
}

用到的NSString扩展类NSString+Extension.m文件中的函数:

//检查图片的后缀是否是支持图片格式
-(BOOL)checkImageFileExtend
{
    if(isEmptyString(self))
    {
        return YES;
    }
    NSString *fileExtend = [self uppercaseString];
    //https://image.oss.m.1-joy.com/2018-09-19/6578b5b7ae171f0d8dcbd628e1bfc6fb.HEIC?x-oss-process=style/wxlookup
    NSArray* fileExtendArr = [fileExtend componentsSeparatedByString:@"?"];
    if(fileExtendArr.count > 1)
    {
        fileExtend = fileExtendArr[0];
    }
    if([fileExtend isEqualToString:@"PNG"] || [fileExtend isEqualToString:@"BMP"] || [fileExtend isEqualToString:@"GIF"] || [fileExtend isEqualToString:@"JPG"] || [fileExtend isEqualToString:@"JPEG"])
    {
        return YES;
    }
    return NO;
}
相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
目录
相关文章
|
10天前
|
存储 Web App开发 Android开发
iOS不支持WebP格式图片解决方案和iPhone 7及其后硬件拍照的HEIC格式图片
iOS不支持WebP格式图片解决方案和iPhone 7及其后硬件拍照的HEIC格式图片
25 1
iOS不支持WebP格式图片解决方案和iPhone 7及其后硬件拍照的HEIC格式图片
|
10天前
|
iOS开发
iOS16.1系统由于一个系统弹窗无法取消,导致屏幕卡死无法关机问题及解决方案
iOS16.1系统由于一个系统弹窗无法取消,导致屏幕卡死无法关机问题及解决方案
19 0
|
11天前
|
iOS开发
iOS中如何显示后台返回的带有html标签的富文本字符串
iOS中如何显示后台返回的带有html标签的富文本字符串
14 0
|
11天前
按钮的image图片是非圆角,直接对UIButton设置圆角,iOS13系统没有圆角效果的问题及解决方案
按钮的image图片是非圆角,直接对UIButton设置圆角,iOS13系统没有圆角效果的问题及解决方案
13 0
|
11天前
|
移动开发 网络协议 安全
iOS审核在ipv6网络下无法访问服务器的问题及解决方案
iOS审核在ipv6网络下无法访问服务器的问题及解决方案
20 0
|
12天前
|
程序员 定位技术 开发工具
iOS11及以上操作系统无法定位问题完美解决方案
iOS11及以上操作系统无法定位问题完美解决方案
18 1
|
19天前
|
API 开发工具 Android开发
iOS 和 Android 平台的开发有哪些主要区别?
iOS与Android开发区别:iOS用Objective-C/Swift,App Store唯一下载渠道;Android用Java/Kotlin,多商店发布(如Google Play、华为市场)。设计上,iOS简洁一致,Android灵活可定制。开发工具,iOS用Xcode,Android用Android Studio。硬件和系统多样性,iOS统一,Android复杂。权限管理、审核流程及API各有特点,开发者需依据目标平台特性进行选择。
55 3
|
3天前
|
编解码 iOS开发 开发者
探索iOS开发中的SwiftUI框架
【5月更文挑战第31天】本文将深入探讨SwiftUI框架,这是Apple为iOS应用开发推出的最新用户界面工具包。我们将分析其核心概念、优势以及如何利用SwiftUI简化和加速开发流程,同时也会触及一些常见的挑战和解决方案。
|
19天前
|
前端开发 Android开发 iOS开发
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
【4月更文挑战第30天】Flutter 框架实现跨平台移动应用,通过一致的 UI 渲染(Skia 引擎)、热重载功能和响应式框架提高开发效率和用户体验。然而,Android 和 iOS 的系统差异、渲染机制及编译过程影响性能。性能对比显示,iOS 可能因硬件优化提供更流畅体验,而 Android 更具灵活性和广泛硬件支持。开发者可采用代码、资源优化和特定平台优化策略,利用性能分析工具提升应用性能。
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比