伴鱼技术团队

Technology changes the world

伴鱼开放平台 上线了! 源于实践的解决方案,助力企业成就未来!

WebP插件修改

一、背景介绍

目前公司的Android项目都使用了WebP插件进行图片的优化。该插件主要是在线上打包系统进行build时才会进行的一个图片优化的动作。通过将PNG图片转换成webp格式减少包体积大小。目前最新的插件版本是1.0.4

二、当前WebP插件的实现

插件的实现机制比较简单,主要是通过三个Gradle Task来完成:

  1. DownloadLibTask
    https://storage.googleapis.com/downloads.webmproject.org/releases/webp/下载对应操作系统的webp工具包。
  2. DecompressTask
    将下载的压缩包解压到特定目录
  3. ConvertTask
    在对drawable资源遍历过程中,使用cwebp命令行工具,对其进行格式转换
    1
    cwebpPath + " -q " + getQuality() + " " + srcFilePath + " -o " + dstFilePath;

通过将dependsOn设定task的依赖关系链,从而完成一系列操作。

1
2
3
4
5
private void attachCovertTaskToBuild(Project project, String variant, Task convertTask) {
String nameOfMergeResources = "convertPics";
Task mergeResources = project.getTasks().findByName(nameOfMergeResources);
mergeResources.dependsOn(convertTask);
}

1
convertTask.dependsOn(decompressTask.dependsOn(downloadTask));

三、当前WebP插件的问题

1. 在线下载不稳定

由于webp命令工具包是在线下载的,因此遇到网络连接失败的时候工具包无法下载,也就导致在线打的包是没有经过图片压缩的,因此包体积可能会大幅增加。试想一下,如果发版前打包出现下载失败的情况是多可怕!另一方面,官方工具包的下载地址也可能会变迁,一旦变迁,也会出现无法进行图片压缩的情况。
对于https://storage.googleapis.com/downloads.webmproject.org/releases/webp/在windows系统下就无法下载到对应的工具包

2. 有些png无法转换格式

在实际打出来的apk包中,依然可以看到有很多png图片存在。说明cwebp在对某些特殊格式的png图片是无法进行webp化的。但是通过tinypng依然可以压缩很多。

3. 压缩体积并不是最优

通过对比tinypng和cwebp转换同一个png图片,可以发现tinypng压缩后的图片要比cwebp的还要小。

四、如何改进

1. TinyPNG?

tinypng平时使用较多,但是用在插件里会存在三个明显的缺陷:

  • 第一是通过API方式进行压缩,也就是走在线方式,速度会比较慢,尤其是涉及到一个APP中大量png进行处理的时候;
  • 第二如果涉及到tinypng服务不稳定的时候,也会出现png不被压缩的情况;
  • 第三是其每一个API Key每月只能免费压缩500张图片,虽然可以多申请一些API Key进行动态替换,但是维护工作过于繁琐。

    2. PngQuant

    通过以上分析,我们可以明确两个基本改进思想:
  • PNG压缩需要本地化,避免线上异常环境的出现
  • 抛弃webp方式改用类tinypng方式,主要是为了实现png压缩的最大化
    通过调研,发现PngQuant这个不错的类库https://pngquant.org/。 按照官网描述,其Features主要有:
  • High-quality palette generation using a combination of vector quantization algorithms.
  • Unique adaptive dithering algorithm that adds less noise to images than the standard Floyd-Steinberg.
  • Easy to integrate with shell scripts, GUIs and server-side software.
  • Fast mode for real-time processing/large numbers of images.
    通过实际体验发现该库非常好用,压缩效果很好。有部分文档指出tinypng同时采用了pngquant、optipng、advpng几种脚本。

    3. 具体实现

  1. 命令行工具本地化
    pngquant
    将不同平台的pngquant命令行工具打入插件包中,避免从网上下载。需要注意的是,官网提供了windows和mac系统的命令行工具,linux系统下需要自己编译或者从对应源进行更新。目前公司的打包机使用的是centoOS。
  2. ExtractPngToolTask
    插件开始工作时,根据当前运行的系统,将对应的命令行工具copy到特定目录。
  3. PngCompressTask
    使用pngquant进行图片压缩
    1
    pngToolPath + " --quality=65-80 " + filePath + " -o " + filePath + " -f"

目前最新版本1.0.5,已上传maven库,可以直接替换使用。

五、潜在风险

使用这种方式压缩的图片还需要UI设计进行审核,避免出现图片压缩导致视觉效果变差。

项目地址https://gitlab.pri.ibanyu.com/gaoguowei9199/webp_plugin,欢迎讨论

欢迎关注我的其它发布渠道