全站webp化!

kelen|2017-04-17


WebP,是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28% 的文件大小。

GraphicsMagick

GraphicsMagick号称图像处理领域的瑞士军刀。 短小精悍的代码却提供了一个鲁棒、高效的工具和库集合,来处理图像的读取、写入和操作,支持超过88种图像格式,包括重要的DPX、GIF、JPEG、JPEG-2000、PNG、PDF、PNM和TIFF。

windows下载地址:ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/windows/ 直接安装即可

linux安装步骤:

首先下载安装包:https://sourceforge.net/projects/graphicsmagick/files/

在包目录下分别执行命令:

gzip -d GraphicsMagick-1.3.tar.gz

tar -xvf ./GraphicsMagick-1.3.tar

./configure

make install

这样就安装好了,gm验证一下,有时候会报以下错误

gm:error while loading shared libraries: libjpeg.so.9: cannot open shared objectfile

解决方法

在/etc/ld.so.conf中加一行/usr/local/lib,然后运行/sbin/ldconfig

最后输入命令 gm -version,发现webP特性为no

在windows下很多功能都默认支持,例如下面

在linux环境下有的格式默认不支持,必须安装第三方库来支持,下载地址

http://www.graphicsmagick.org/README.html

首先下载安装webp安装,然后重复上面步骤重新安装gm即可。

node的gm模块

nodejs开发对图片的处理可以在上面环境配置好的前提下,利用 gm 模块来用nodejs轻松实现gm的功能

然后通过一行代码就可以实现webp的转换

gm("./test.png").write("./test.webp");

gm模块不仅可以转webp,还可以实现压缩,固定大小等图片处理功能!

gm模块高级应用

gm模块本身提供很多常用方法,或许够用,我们可以自己定制参数

官方的文档

gm().command() - 定制命令例如 identify or convert
gm().in() - 定制输入的参数
gm().out() - 定制输出的参数

按以下顺序格式化命令:

  1. command - ie convert
  2. in - the input arguments
  3. source - stdin or an image file
  4. out - the output arguments
  5. output - stdout or the image file to write to

 例如有以下命令

gm "convert" "label:Offline" "PNG:-"

如果这样写的话

gm()
.label('Offline')
.stream();

// 会转换成
gm "convert" "-label" "\"Offline\"" "PNG:-"

这样不对,所以可以自定义参数

gm()
.out('label:Offline')
.stream();

// 转换成
gm "convert" "label:Offline" "PNG:-"

抱歉,还是看太懂,所以看下面命令吧! 

var imageMagick = gm.subClass({ imageMagick: true });
// 例如有下面一条命令
// convert wizard.png -quality 50 -define webp:lossless=true wizard.webp
imageMagick("./test.png").in("-quality", 100).in("-define", "webp:lossless=true").write('./test2.webp', function(err, res) {
    console.log(err, res);
})

========================================== 坑爹线 ==========================================

马丹,第二天发现其实webp在苹果浏览器和火狐浏览器还不兼容

只有chrome浏览器,果真是谷歌的亲儿子,那么其他浏览器就看不到图片了,于是找了下面两种解决方法

  • 利用webpjs或者webppy插件来实现
  • 当页面不支持webp的时候,更换链接重新从服务器拉取常规格式的图片

经过测试,第一种有一些webp格式莫名不能转换成base64格式的数据,原因可能是 gm转换时强制转webp导致图片数据格式不对,插件无法正确转换base64格式,所以我还是用第二种

检查浏览器是否支持webp的js代码

supportWebp: (function() {
    // webp功能测试数据
    var images = {
        basic: "data:image/webp;base64,UklGRjIAAABXRUJQVlA4ICYAAACyAgCdASoCAAEALmk0mk0iIiIiIgBoSygABc6zbAAA/v56QAAAAA==",
        lossless: "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA="
    };
    return function(feature) {
        return new Promise(function(resolve, reject) {
            var img = new Image();
            img.onload = function() {
                if (this.width === 2 && this.height === 1) {
                    resolve();
                } else {
                    reject();
                }
            }
            img.onerror = function() {
                reject();
            }
            img.src = images[feature || 'basic'];
        })
    }
})()

使用方法如下

supportWebp().then(function() {
    // 支持
}).catch(function() {
    // 不支持,更换src链接
})

于是解决了不兼容webp浏览器的问题,如果有单独的静态资源服务器就更好了!