图片压缩上传/加载方案

1,326 阅读4分钟

一、图片压缩上传方案

图片压缩上传,在对图片无损的前提下,压缩图片大小,加快上传与渲染速度,提升用户体验。

压缩图片基本流程

  • input 读取到 文件 ,使用 FileReader 将其转换为 base64 编码
  • 新建 img ,使其 src 指向刚刚的 base64
  • 新建 canvas ,将 img 画到 canvas 上
  • 利用 canvas.toDataURL/toBlob 将 canvas 导出为 base64 或 Blob
  • 将 base64 或 Blob 转化为 File

将这些步骤逐个拆解,我们会发现似乎在canvas.toDataURL时涉及到图片质量,那咱们就从这里下手。

关键知识点

HTMLCanvasElement.toDataURL()

MDN: HTMLCanvasElement.toDataURL()

HTMLCanvasElement.toDataURL() 方法返回一个包含图片展示的 data URI 。可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi

  • 如果画布的高度或宽度是0,那么会返回字符串“data:,”。
  • 如果传入的类型非“image/png”,但是返回的值以“data:image/png”开头,那么该传入的类型是不支持的。
  • Chrome支持“image/webp”类型。

语法

canvas.toDataURL(type, encoderOptions);

参数

  • type 可选
    图片格式,默认为 image/png
  • encoderOptions 可选
    在指定图片格式为 image/jpegimage/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。

返回值

包含 data URIDOMString

方法应用

默认值得到的图片往往比原图的图片质量要高。
当quality在0.2~0.5之间,图片质量变化并不大,quality的值越小,压缩效率越可观(也就是在0.2左右时,压缩图片可以最大化,同时并不对图片质量造成太大影响)

二、图片高性能加载方案

包含了大量图片素材的 H5 页面,呈现给用户之前,至少要等待首屏加载完成;要提升加载速度,一方面请求的响应速度要足够快,另一方面要尽量减小传输的数据量。建议网站上的图片文件大小不应该超过 500 KB

高清晰度、高压缩比、小体积的诉求出发,最终选择了使用 WebP 作为首选图片文件格式。

为什么选webp

WebP 是 Google 研发的具有先进有损无损压缩算法的图片格式,主要的特点有:高压缩率、支持透明通道、支持动图。据 WebP 官网的描述,在图片质量等同的条件下,WebP 无损压缩后的图片文件大小比对应的 PNG 图片小 26%,有损压缩图片比对应 JPEG 图片小 25~34%

无损 WebP 也支持透明度。而在可接受有损 RGB 压缩的情况下,有损 WebP 也支持透明度,通常 PNG 文件大小比它大三倍

Google 报告称,把动画 GIF 文件转换为有损 WebP 后文件大小减少了 64%,转换为无损 WebP 后文件大小减少了 19%

WebP 文件格式是一种基于 RIFF(资源互换文件格式(resource interchange file format))的文档格式。

使用 WebP 对图片进行有损压缩,在默认配置 75%压缩比下,可以将 PNG 图片大小压缩至原图体积的 13% 左右,JPG 图片甚至可以压缩至原图体积的 10% 左右(可参考官方测试页面),实际效果显著。

相比于其他相同大小、不同格式的压缩图像,WebP 格式的图片拥有更小的体积以及更高的质量,优势十分明显。

webp方案使用

  • 判断宿主环境是否支持WebP JavaScript检测是否支持WebP代码如下:(出自Google官方文档)
function check_webp_feature(feature, callback) {
    var kTestImages = {
        lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
        lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
        alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
        animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
    };
    var img = new Image();
    img.onload = function () {
        var result = (img.width > 0) && (img.height > 0);
        callback(feature, result);
    };
    img.onerror = function () {
        callback(feature, false);
    };
    img.src = "data:image/webp;base64," + kTestImages[feature];
}
  • 生成webp格式图片 NODE生成:调用图片转化库生成对应的webp图片 or 利用webpack对应loader生成 前端转码处理生成
  • CSS背景图引入webp 设置根节点webpa类来处理css中图片引入问题
  • html中图片如何引入 JS判断动态改变图片URL

本文主要参考
前端图片最优化压缩方案
基于 WebP 的图片高性能加载方案