iOS 利用libwebp库将图片转webP格式总结

本篇文章主要写的是转换过程中遇到的几个令人头疼的问题并解决,转换的和显示的主要代码参考了SDWebImage/Web和# iOS-WebP
使用的库:'libwebp','~> 1.0.0'

1.遇到的问题及解决

出问题的图片主要是iphone6及以上手机截频的图片,这种图片有一个共同特性:包含Alpha通道;以及少部分不包含Alpha通道且从网络下载的图片。

1> 图片转换后无法显示

这个问题出现在iOS11及以上系统机型。
主要原因:
如下方法中代码:

+ (UIImage *)imageWithWebPData:(NSData *)imgData error:(NSError **)error;

有误代码:

CGDataProviderRef provider = CGDataProviderCreateWithData(config, data, config->options.scaled_width  * config->options.scaled_height * 4, free_image_data);

config->options.scaled_width和config->options.scaled_height的值都为0;
解决:

CGDataProviderRef provider = CGDataProviderCreateWithData(&config, data,width * height * 4 , free_image_data);
2> 转换成webP直接在google浏览器显示或者再转换成png显示后的样式
图1

解决:
方法:

+ (NSData *)convertToWebP:(UIImage *)image
       compressionQuality:(CGFloat)quality
                    alpha:(CGFloat)alpha
                   preset:(WebPPreset)preset
              configBlock:(void (^)(WebPConfig *))configBlock
                    error:(NSError **)error;

旧代码:

 if (alpha < 1) {
        image = [self webPImage:image withAlpha:alpha];
    }

新代码:

        image = [self webPImage:image withAlpha:alpha];

修改代码转换后的样式:


iOS 利用libwebp库将图片转webP格式总结_第1张图片
图2

依旧有问题。

3> 最后一步

经过测试发现只有将从相册或者拍照获取的图片按照宽 = 320的整倍数,高 = 320 /(原始图片宽/原始图片高)的方式转换后,才能完整的将图片转换为webP并展示。
方法:

+ (NSData *)convertToWebP:(UIImage *)image
       compressionQuality:(CGFloat)quality
                    alpha:(CGFloat)alpha
                   preset:(WebPPreset)preset
              configBlock:(void (^)(WebPConfig *))configBlock
                    error:(NSError **)error;

加入新的代码:

 CGFloat scale = image.size.width / image.size.height;
    CGFloat imageWidth = 320 * 2;
    if (image.size.width > 1000){
        imageWidth = 320 * 3;
    }
    UIImage *resizeImage = [self imageResize:image size:CGSizeMake(imageWidth,imageWidth/scale)];
     resizeImage = [self webPImage:resizeImage withAlpha:alpha];
    CGImageRef webPImageRef = resizeImage.CGImage;

新代码转换后的效果:


iOS 利用libwebp库将图片转webP格式总结_第2张图片
图3

如果不按这种比列去转换则会出现如下样式:

 UIImage *resizeImage = [self imageResize:image size:CGSizeMake(414,736)];
iOS 利用libwebp库将图片转webP格式总结_第3张图片
图4
  • (UIImage)imageResize:(UIImage)image size:(CGSize)size ;方法实现的代码
+ (UIImage*)imageResize:(UIImage*)image size:(CGSize)size {
    UIGraphicsBeginImageContext(size);
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}
4> 最最最后一步

经过以上散步发现直拖入到项目内部的图片可以正常转换和展示了,但是经过photos框架从相册中获取的图片仍然无法正常转换。
解决办法如下:

UIImage *convertImage = [UIImage imageWithData:UIImageJPEGRepresentation(image, 1.0)];

将从相册中的获取的图片通过UIImageJPEGRepresentation装换成data再转换为UIImage,将现在在的image执行上诉的1,2,3步即可获。
完整代码如下:

+ (NSData *)convertToWebP:(UIImage *)image
       compressionQuality:(CGFloat)quality
                    alpha:(CGFloat)alpha
                   preset:(WebPPreset)preset
              configBlock:(void (^)(WebPConfig *))configBlock
                    error:(NSError **)error
{
    UIImage *convertImage = [UIImage imageWithData:UIImageJPEGRepresentation(image, 1.0)];
    CGFloat scale = convertImage.size.width / convertImage.size.height;
    CGFloat imageWidth = 320 * 2;
    if (convertImage.size.width > 1000){
        imageWidth = 320 * 3;
    }
    UIImage *resizeImage = [self imageResize:convertImage size:CGSizeMake(imageWidth,imageWidth/scale)];
    resizeImage = [self webPImage:resizeImage withAlpha:alpha];
    CGImageRef webPImageRef = resizeImage.CGImage;
    size_t webPBytesPerRow = CGImageGetBytesPerRow(webPImageRef);
    
    size_t webPImageWidth = CGImageGetWidth(webPImageRef);
    size_t webPImageHeight = CGImageGetHeight(webPImageRef);
   ... ...

2.其它

我们服务器为了减小服务器存储图片空间的大小,经过调研选用webP格式图片为最佳的方案。但是同事在调研时未能测试出以上问题。我接手这个问题开始以为是相册框架的问题,经过测试排除。前后总共花了两天时间测试才解决了这个几个坑,以下是demo地址:https://github.com/moreFine/WWWebPConvert

你可能感兴趣的:(iOS 利用libwebp库将图片转webP格式总结)