在米扑博客的前两篇博客,已经介绍了 webp 图片格式,详见米扑博客:

WordPress 支持 WebP格式图片上传方法

CentOS 将 png、jpg/jpeg、gif 图片转换成webp图片

本文,主要介绍 浏览器检测支持 webp 和 png/jpg/jpeg 图片的兼容性解决方案

 

webp 图片格式介绍Wikipedia 、百度百科

WebP最初在2010年释出,WebP使用VP8作为压缩演算法,目标是减少档案大小,但达到和JPEG格式相同的图片品质,希望能够减少图片档在网路上的传送时间。

webp是一种同时提供了有损压缩与无损压缩的图片档案格式 ,衍生自影像编码格式VP8,是由Google在购买On2 Technologies后发展出来,以BSD授权条款释出。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28% 的文件大小。

在线查看webp压缩比,可以登录:https://zhitu.isux.us (智图)

对比本地和智图的png、jpeg、jpg、webp,大小略有不同

 

使用webp可以使图片体积更小从而达到极大提升图片加载速度的效果,并且也能降低服务器带宽和流量成本

简单来说就是2个方面的好处:

1)用户体验:更少的加载时间,减少等待;

2)节约成本:更少的带宽、流量,节省建站成本

 

webp 图片优势

同质量的前提下,WebP体积大约只有JPEG的1/3,对于采用大量图片的网页,WebP格式可以节省大量带宽,大幅提升网页加载速度。

例如:

YouTube的视频略缩图采用WebP格式后,网页加载速度提升了10%;

谷歌的Chrome 网上应用商店采用WebP格式图片后,每天可以节省几TB的带宽,页面平均加载时间大约减少1/3;

Google+移动应用采用WebP图片格式后,每天节省了50TB数据存储空间。

 

webp 使用场景

对于图片占主要流量的网站,使用webp格式图片能很大程度减小图片体积,

在之前的一个项目里,首页是四张大图的轮播,图片优化很成问题,

在使用webp格式图片后,图片体积减小了70%以上,目测图片质量没有影响

 

webp  格式图片支持的浏览器

注:蓝色表示支持,红色表示不支持,Apple Safari 浏览器都不支持 webp,打不开

 

在线图片转换工具:

CloudConvert:https://cloudconvert.com/jpeg-to-webp

isparta:http://isparta.github.io (软件,支持 Windows、MacOS、Linux)

converter:https://www.office-converter.com/JPEG-to-JPG

ezgif.com:https://ezgif.com/webp-to-gif

squooshhttps://squoosh.app (谷歌出品,github

GIF vs APNGhttp://littlesvr.ca/apng/gif_vs_apng.html

sojson:https://www.sojson.com/image/format.html

智图:https://zhitu.isux.us (推荐,在线和软件转化,腾讯ISUX前端团队开发),开源插件:gulp-imageisux

朝夕网:https://pic.zhaoxi.net

做好图:http://www.zuohaotu.com/image-converter.aspx (不支持 webp格式)

我拉网:http://pic.55.la  (不支持 webp格式)

改图宝:https://www.gaitubao.com/jpg-gif-png  (不支持格式转换)

Chrome 插件:Save image as Type (推荐),WebP Highlighter

 

 

js 判断浏览器支持webp的方法

使用WebP格式的图准备两种格式的图片:一种是原图原格式,另一种是WebP图片

上文介绍了webp浏览器兼容性,蓝色表示支持,红色表示不支持,Apple Safari 浏览器都不支持 webp,打不开

通过判断浏览器是否支持WebP,如果支持就显示WebP图,如果不支持就显示原图

这样我们就可以很妥善地解决WebP图的兼容性问题,最大限度地做到图片最优化。

一来,不会因为只放WebP图,从而影响不支持WebP的浏览器用户,这样比图片加载慢更可怕;

二来,也不会WebP的兼容性问题而放弃使用WebP,这样也就体验不到WebP给我们带来的好处。

总之,要恰到好处地使用WebP,实现方法有两种。

 

1、PC端,触屏版

前端JS方案:利用img标签加载一张base64的WebP图片,在img标签的onload事件中判断该图片是否具有宽高的属性,若有表示支持webP,若没有表示不支持webP。

后台方案:判断浏览器请求头Accept是否支持WebP,返回是否支持的标示给前台。

以上两种方案中,前端方案为佳,当JS被禁止的时候,可以使用后台判断方式执行判断

 

2、iOS独立版

用户直接拉取WebP格式的图片(如果CDN有存储),下载完成后在前端实时转码(前端开发的WebP SDK),将WebP图片转换为jpg或png图片,展示给用户的是普通图片。

这样做的好处在于下载WebP的时候节省了带宽,虽然在转码的时候会耗时,但是由于下载时间缩短中和了转码的时间,所以用户基本感觉不出来差别。

我们在不延长用户等待时间的同时缩小图片体积,节省了带宽。

 

3、安卓独立版

后台判断用户机器系统,当系统版本大于4.0的时候返回支持WebP标示(因为其原生支持),前端拉取图片时后台会根据这个标示决定使用原格式图片还是WebP格式的图片。

4、兼容方案

对于不支持WebP的浏览器,可根据是否支持WebP的判断来拉取jpg或者png图片,也可以使用flash作为载体来加载WebP图片(空间相册兼容低端浏览器方案) 。

5、用户下载图片另存为 jpg/png 格式

PC和webview方案中,用户若想将图片另存为本地(可能本地不支持WebP预览展示,例如:Macbook就不支持webp本地预览),可在用户右击“另存为”的时候,绑定右击事件,加载当前WebP图片对应的jpg图片,然后直接下载jpg图片(空间相册方案),例如: Chrome 插件 Save image as Type (推荐

虽然这样的做法会导致多加载一张图片,但是由于只在右击时候触发加载,而且用户右击“另存为”的行为较少,消耗可不计。

 

方法1: 请求头相关字段

通过 Chrome 浏览器开发者工具抓包显示,可以通过查看响应头和请求头相关字段,判断其Accept里是否含有 image/webp 字段,如果包含则说明支持WebP,反之则不支持

The HTMLCanvasElement.toDataURL() method returns a data URI containing a representation of the image in the format specified by the type parameter (defaults to PNG). The returned image is in a resolution of 96 dpi.

If the height or width of the canvas is 0, the string "data:," is returned.
If the requested type is not image/png, but the returned value starts with data:image/png, then the requested type is not supported.
Chrome also supports the image/webp type.

js 代码:

var checkWebp = function(){
    try{
        return (document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0);
    }catch(err) {
        return  false;
    }
}
isWebP = checkWebP() //isWebP为true则支持WebP,若为false则不支持WebP

 

方法2:宽高判断法

先加载一个WebP图片,如果能获取到图片的宽度和高度,就说明是支持WebP的,反之则不支持。

js 代码:

var isWebP = false;
var img = new Image();
img.onload = function(){
    isWebP = !!(img.height>0 && img.width>0);
    checkPic(isWebP);
};
img.onerror = function(){
    isWebP = false;
    checkPic(isWebP);
};
img.src = './c.webp';
var checkPic = function(isWebP){
    $("#pics img").each(function(i,v){
        var src = isWebP?$(v).attr('webppic-src'):$(v).attr('pic-src');
        $(v).attr('src',src);
    })
}

 

还有一种巧妙设计,但可读性不高(如下的js不推荐)

var d = document;
var check = function() {
    var supportWebp;
    try {
        var ele = d.createElement('object');
        ele.type = 'image/webp';
        ele.innerHTML = '!';
        d.body.appendChild(ele);
        //奇妙所在,如果浏览器支持webp,那么这个object是不可见的(offsetWidth为0),
        //否则就会显示出来,有可视宽度.
        supportWebp = !ele.offsetWidth;
        d.body.removeChild(ele);
    }catch (err) {
        supportWebp = false;
    }
    return supportWebp;
}

 

小结

以上两种方法总结合成一个,实际使用的时候,选择其中一种使用就行了,把另外一个方法代码去掉,切勿同时使用,以免出错。

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<div id="pics">
    <img src="" pic-src="./c.jpg" webppic-src="./c.webp">
    <img src="" pic-src="./c.jpg" webppic-src="./c.webp">
    <img src="" pic-src="./c.jpg" webppic-src="./c.webp">
</div>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
// 公共方法,操作放原图还是放WebP图
var checkPic = function(isWebP){
    $("#pics img").each(function(i,v){
        var src = isWebP?$(v).attr('webppic-src'):$(v).attr('pic-src');
        $(v).attr('src',src);
    })
}
// 第一种方法
var isWebP = false;
var img = new Image();
img.onload = function(){
    isWebP = !!(img.height>0 && img.width>0);
    checkPic(isWebP);
};
img.onerror = function(){
    isWebP = false;
    checkPic(isWebP);
};

 

WordPress 无法上传webp图片格式

错误提示:Web 服务器无法处理该图片,请在上传前将其转换为 JPEG 或 PNG 格式。

解决办法:编辑文件 vim ./wp-includes/media.php把 true 改为 false

4213         // Check if WebP images can be edited.
4214         if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {
4215                 $defaults['webp_upload_error'] = true;   // 将此处 true 改为 false
4216         }

 

让浏览器支持 webp

1. 若使用场景是浏览器,可以:

JavaScript 能力检测,对支持 WebP 的用户输出 WebP 图片

使用 WebP 支持插件:WebPJS

 

2. 若使用场景是 App,可以:

Android 4.0 以下 WebP 解析库(链接

iOS WebP 解析库(链接

 

3. Chrome 插件

Save image as Type (推荐),WebP Highlighter

 

 

参考推荐:

WordPress 支持 WebP格式图片上传方法

CentOS 将 png、jpg/jpeg、gif 图片转换成webp图片

让你的页面支持WebP