Webp压缩实践 2022-11-10 周四

2022-11-11  本文已影响0人  勇往直前888

简介

在iOS原生的图片压缩算法中,系统提供了PNG和JPEG两种压缩方式(NSData),用来进行网络传输。
PNG一般用在图标中;稍微大一点图片,一般都会采用JPEG格式。

问题

就算采用JPEG方式压缩,系数缩小到0.5,仍然感觉图片太大。如果把系数缩小到0.3,那么图片质量就不可接受了,会出现红斑。所以,希望在保证图片质量的前提下,缩小图片的大小。

WebP

搜索一番,发现还真有比JPEG更好的压缩方式。这个格式就是webp。
WebP 极限压缩及ios实现

企业微信截图_78bfb084-5771-4ccd-8bad-e2f91e0ec24d.png

实现1

既然webp这么好,那么就试一试。当然,不会真的像上面的文章写的那样自己去写编码方式。找第三方库的实现,发现还真有。

WebPImageSerialization

企业微信截图_ea367e50-2622-445f-ac19-435c10c336f4.png

集成

集成很简单,添加一个framework和两个文件就好。使用也很方便。参考一下提供的例子就明白了。

企业微信截图_67ab175f-cac4-42ef-b537-2b9c56beb0b8.png

压缩效果明显

企业微信截图_be5fc988-1f55-4116-8e99-38dabc4f9746.png 企业微信截图_4bccfeb7-9514-4bcc-9af9-df0c09e46d7a.png

问题:图片严重失真

压缩前.png 压缩后.png

纠结

实现2:

关于iOS中显示WEBP图像的学习记录

iOS-WebP 网站

iOS-WebP gitHub

手动集成遇到困难,demo中用到的.a文件不好处理。用pod集成,版本号要去掉;并且编译不同过。 出现 Multiple commands produce问题,按照相关文章修改,没有作用。

+ (void)imageToWebP:(UIImage *)image quality:(CGFloat)quality alpha:(CGFloat)alpha preset:(WebPPreset)preset
    completionBlock:(void (^)(NSData *result))completionBlock
       failureBlock:(void (^)(NSError *error))failureBlock;

+ (void)imageWithWebP:(NSString *)filePath
      completionBlock:(void (^)(UIImage *result))completionBlock
         failureBlock:(void (^)(NSError *error))failureBlock;

实现3:YYImage

YYImage中包含webp的编码和解码,真是意外之喜。

安装

pod 'YYImage'
pod 'YYImage/WebP'
企业微信截图_009acc1e-a0b7-45d9-b25c-fed5692a4210.png

代码样例

// Encode animated image:
YYImageEncoder *webpEncoder = [[YYImageEncoder alloc] initWithType:YYImageTypeWebP];
webpEncoder.loopCount = 5;
[webpEncoder addImage:image0 duration:0.1];
[webpEncoder addImage:image1 duration:0.15];
[webpEncoder addImage:image2 duration:0.2];
NSData webpData = [webpEncoder encode];

样例代码中没有quality参数,为什么?

- (instancetype)initWithType:(YYImageType)type {
    if (type == YYImageTypeUnknown || type >= YYImageTypeOther) {
        NSLog(@"[%s: %d] Unsupported image type:%d",__FUNCTION__, __LINE__, (int)type);
        return nil;
    }
    
#if !YYIMAGE_WEBP_ENABLED
    if (type == YYImageTypeWebP) {
        NSLog(@"[%s: %d] WebP is not available, check the documentation to see how to install WebP component: https://github.com/ibireme/YYImage#installation", __FUNCTION__, __LINE__);
        return nil;
    }
#endif
    
    self = [super init];
    if (!self) return nil;
    _type = type;
    _images = [NSMutableArray new];
    _durations = [NSMutableArray new];

    switch (type) {
        case YYImageTypeJPEG:
        case YYImageTypeJPEG2000: {
            _quality = 0.9;
        } break;
        case YYImageTypeTIFF:
        case YYImageTypeBMP:
        case YYImageTypeGIF:
        case YYImageTypeICO:
        case YYImageTypeICNS:
        case YYImageTypePNG: {
            _quality = 1;
            _lossless = YES;
        } break;
        case YYImageTypeWebP: {
            _quality = 0.8;
        } break;
        default:
            break;
    }
    
    return self;
}

单张图片编码接口

/**
 Convenience method to encode single frame image.
 @param image   The image.
 @param type    The destination image type.
 @param quality Image quality, 0.0~1.0.
 @return The image data, or nil if an error occurs.
 */
+ (nullable NSData *)encodeImage:(UIImage *)image type:(YYImageType)type quality:(CGFloat)quality;
+ (NSData *)encodeImage:(UIImage *)image type:(YYImageType)type quality:(CGFloat)quality {
    YYImageEncoder *encoder = [[YYImageEncoder alloc] initWithType:type];
    encoder.quality = quality;
    [encoder addImage:image duration:0];
    return [encoder encode];
}

压缩效果,跟JPEG比较

        // 压缩效果对比
        NSData *pngData = UIImagePNGRepresentation(scaledImage);
        NSInteger pngLength = pngData.length / 1000;
        
        NSData *jpegData = UIImageJPEGRepresentation(scaledImage, compressionQuality);
        NSInteger jpegLength = jpegData.length / 1000;
        
        NSData *webpData = [YYImageEncoder encodeImage:scaledImage type:YYImageTypeWebP quality:compressionQuality];
        NSInteger webpLength = webpData.length / 1000;
企业微信截图_0073ab9c-155f-40b8-ba8a-b33e2bef691a.png 企业微信截图_5127ce19-0296-4f78-bfff-62a447eba036.png 压缩前.png

WebP压缩后:

企业微信截图_ae9c3522-2fc8-4900-bfca-dbf623a35449.png

看上去差不多,效果不错。

小结

经过对比,可以看出YYImage优势明显,使用起来也很方便。

上一篇 下一篇

猜你喜欢

热点阅读