微信小程序> [iOS]系统升级后应用无法展示WebP格式图片问题

[iOS]系统升级后应用无法展示WebP格式图片问题

浏览量:1960 时间: 来源:枫志应明
[iOS]系统升级后应用无法展示WebP格式图片问题资源:

https://github.com/rs/SDWebImage
https://github.com/ibireme/YYImage
https://github.com/ibireme/YYWebImage
http://blog.csdn.net/zhonggaorong/article/details/51283448
https://www.jianshu.com/p/30c3b7881b68
备份:SDWebImage、YYImage
http://download.csdn.net/download/u012881779/10191229

比较惭愧,虽然问题解决了,但并未找到为什么系统升级会导致WebP解析失败的原因,希望知道的朋友分享一下。

情况介绍:
前段时间新供职公司所有线上APP出了一个问题,苹果手机升级11.2后应用中解析WebP格式图片全部失败。这套APP核心功能是用户DIY家装场景,由于需要网络请求并快速展示大量图片,设计之初就决定使用现在比较流行的WebP格式来提高功能的流畅性。实话说之前对WebP不怎么了解,只知道是谷歌(google)开发的一种加快图片加载速度的图片格式,然而苹果并不支持,若一定需要使用WebP则需要在本地通过代码或工具将之转换为jpg或png。我的前任公司上个程序员是使用第三方SDWebImage来加载webp,如图一SDWebImage有个WebP.framework框架,在加载网络图片时已经支持WebP格式。但是SDWebImage对WebP格式支持得不完美,当然也可能是我们使用的版本有问题。据我向同事了解,以前系统升级时加载WebP也曾出现过无法解析的问题,那么如今再次出现同样的问题就感觉有点危险。
查看UIImage+WebP.m中解析源码发现,iOS11.1这方法能正常解析Data为image,但iOS11.2这个方法就无法解析Data了。
+ (UIImage *)imageWithWebPData:(NSData *)imgData error:(NSError **)error{    // `WebPGetInfo` weill return image width and height    int width = 0, height = 0;    if(!WebPGetInfo([imgData bytes], [imgData length], &width, &height)) {        NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary];        [errorDetail setValue:@"Header formatting error." forKey:NSLocalizedDescriptionKey];        if(error != NULL)            *error = [NSError errorWithDomain:[NSString stringWithFormat:@"%@.errorDomain",  [[NSBundle mainBundle] bundleIdentifier]] code:-101 userInfo:errorDetail];        return nil;    }        WebPDecoderConfig config;    if(!WebPInitDecoderConfig(&config)) {        NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary];        [errorDetail setValue:@"Failed to initialize structure. Version mismatch." forKey:NSLocalizedDescriptionKey];        if(error != NULL)            *error = [NSError errorWithDomain:[NSString stringWithFormat:@"%@.errorDomain",  [[NSBundle mainBundle] bundleIdentifier]] code:-101 userInfo:errorDetail];        return nil;    }    config.options.no_fancy_upsampling = 1;    config.options.bypass_filtering = 1;    config.options.use_threads = 1;    config.output.colorspace = MODE_RGBA;        // Decode the WebP image data into a RGBA value array    VP8StatusCode decodeStatus = WebPDecode([imgData bytes], [imgData length], &config);    if (decodeStatus != VP8_STATUS_OK) {        NSString *errorString = [self statusForVP8Code:decodeStatus];        NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary];        [errorDetail setValue:errorString forKey:NSLocalizedDescriptionKey];        if(error != NULL)            *error = [NSError errorWithDomain:[NSString stringWithFormat:@"%@.errorDomain",  [[NSBundle mainBundle] bundleIdentifier]] code:-101 userInfo:errorDetail];        return nil;    }        // Construct UIImage from the decoded RGBA value array    uint8_t *data = WebPDecodeRGBA([imgData bytes], [imgData length], &width, &height);    CGDataProviderRef provider = CGDataProviderCreateWithData(&config, data, config.options.scaled_width  * config.options.scaled_height * 4, free_image_data);    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault |kCGImageAlphaLast;    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;        CGImageRef imageRef = CGImageCreate(width, height, 8, 32, 4 * width, colorSpaceRef, bitmapInfo, provider, NULL, YES, renderingIntent);    UIImage *result = [UIImage imageWithCGImage:imageRef];     // Free resources to avoid memory leaks    CGImageRelease(imageRef);    CGColorSpaceRelease(colorSpaceRef);    CGDataProviderRelease(provider);    WebPFreeDecBuffer(&config.output);        return result;}
一开始确定是解析失败导致WebP无法展示时,个人觉得实力不够搞定不了这个问题,感觉很无力。还好当时手上有更重要的项目在限期开发,这问题被压下暂时搁置了几天。经常开玩笑说,这问题要升级最新iOS系统才会发生,“手贱”点升级系统的人活该!
解决方案:
前两天重新思考解决这个问题时,发现很简单并没有想象中复杂。我们已经获取到了WebP的data,要最小代价的修复问题,只需要重写上面那个解析方法将WebP的data转换成UIImage并返回就行了,下面主要是按照这个思路。百度WebP如何转换成jpg时,发现有人推荐YYImage支持WebP、APNG、GIF格式动画图像的播放/编码/解码。苹果不是不支持webp格式么,那么这个YYImage的demo中就一定也存在WebP的data转换Image的方法,只要这个方法与SDWebImage中的方法不一样那么之前的问题就解决了。
如图二发现WebP.framework框架更丰富,查看YYImage.h有方法“+ (nullable YYImage *)imageWithData:(NSData *)data;”。那么导入项目重写方法WebP无法展示的问题就得到了解决。
+ (UIImage *)imageWithWebPData:(NSData *)imgData error:(NSError **)error{    UIImage *webpImage = [YYImage imageWithData:imgData];    return webpImage;}

[图一]小程序
[图二]小程序
小程序

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

最新资讯

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎