4

SDWebImage 为什么无法读取 webpmux 生成的 WebP 动图?

 2 years ago
source link: https://www.isaced.com/post-289.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

SDWebImage 为什么无法读取 webpmux 生成的 WebP 动图?

前几天有个需求是需要把一些 JPG 图片转换成 WebP 然后放到客户端里播放动图,主要是想享受 WebP 格式带来的压缩率,生成更小的图片文件,节省带宽和下载时间。

webpmux 是什么?

webpmux 是 Google 为其 WebP 出得附属配套工具,专门用来操作 WebP 动图,可以从 WebP 动图里抽出每一帧,也可以从一批图像帧合成成一张 WebP 动图,同时也支持设定循环次数、背景颜色,每一帧的播放时长、暂停时间等等。

为什么解不开?

由于 webpmux 的 file_i +di[+xi+yi[+mi[bi]]] 参数 BLEND 项默认为 +b (BLEND) 所以导致我们生成的 WebP 动图用 SDWebImage 解析不出来。

因为 SDWebImage/UIImage+WebP.m 中判断如果当前帧 为 WEBP_MUX_BLEND 则用 sd_blendWebpImageWithOriginImage 解,否则用 sd_rawWepImageWithData 方法

    ...
    do {
        UIImage *image;
        if (iter.blend_method == WEBP_MUX_BLEND) {
            image = [self sd_blendWebpImageWithOriginImage:[images lastObject] iterator:iter];
        } else {
            image = [self sd_rawWepImageWithData:iter.fragment];
        }
        
        if (!image) {
            continue;
        }
        
        [images addObject:image];
        duration += iter.duration / 1000.0f;
        
    } while (WebPDemuxNextFrame(&iter));
    ...

sd_blendWebpImageWithOriginImage 又需要取到上一帧做 blend 叠加,由于第一帧被指定成了 BLEND,所以导致后面所有帧都解不出来。

+ (nullable UIImage *)sd_blendWebpImageWithOriginImage:(nullable UIImage *)originImage iterator:(WebPIterator)iter {
    if (!originImage) {
        return nil;
    }
    ...
}

解决办法就是显示指定 webpmux 的 BLEND 参数为 -b (NO_BLEND),让第一帧不使用混合模式,SDWebImage 就能正确解析了。

webpmux -frame 0.webp +100+0+0+0-b \
  -frame 1.webp +100+0+0+0-b \
  -frame 2.webp +100+0+0+0-b \
  -frame 3.webp +100+0+0+0-b \
  -o anim.webp

另外 YYWebImage 的 WebP 解码方式好像是有些不太一样,没有细看,所以用 YY 应该是没问题的。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK