WebShell中实现前端图片压缩

· 2 min read

最近调研前端图片压缩,这里总结下

MIME

media type

<input type="file" id="selectImg" accept="image/*"/>
  1. 比如图片上传选择框进行限制,非图片类不可选,则可以使用image/*
  2. 该限制比如在Windows下可以被绕开,因此在提交逻辑/后端还可以再严格限制下,方案也是通过mime
 if (!file.type.startsWith('image/')) {
      e.target.value = '';
      return;
    }

压缩手段

  1. 尺寸

    可以通过调整图像的像素尺寸来减小文件大小

  2. 质量

    图像的压缩质量通常是通过牺牲图像的细节和准确信息来实现的

格式对比

https://static.1991421.cn/2023/2023-04-05-124346.jpeg

兼容性

  • JPEG 2000 by the JPEG group, the oldest of the JPEG successors, available in Safari
  • WebP by Google, available in all browsers
  • HEIC by the MPEG group, based on HEVC and available in iOS
    • 各浏览器均不支持
  • AVIF by the Alliance for Open Media (AOM), available in Chrome and Firefox
  • JPEG XL by the JPEG group, the next-generation codec
  • WebP2 by Google, an experimental successor to WebP

前端压缩可行性

  • canvas

Compressor.js

 new Compressor(selectedImg, {
      strict: true,
      quality: 0.6,
      maxHeight: 2160,
      maxWidth: 3840,
      convertSize: 2000000,
      mimeType: 'auto',
      success(result) {
       
      },
      error(err) {
        console.log(err.message);
      },
    });

自动降级显示图片

HTML img

<picture>
  <source srcset="111.avif" type="image/avif">
  <source srcset="111.webp" type="image/webp">
  <img src="111.png">
</picture>

CSS background-image

css层面目前没有最有效的方式,推荐走JS判断确定当前系统是否支持avif/webp,从而确定显示对应图片。

function isAvifSupported() {
  return new Promise(resolve => {
      var image = new Image();
  
      image.onload = function() {
        resolve(true);
      };
      image.onerror = function() {
        resolve(false);
      };
  
      image.src = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
    });
}

网上检索到的@supports方式存在问题,比如Mac BigSur+Safari16下,命中但实际并不支持avif从而造成显示黑屏。

写在最后

由上我们可以有几点收获

  1. 权衡兼容性可以尝试使用avif/webp格式
  2. 前端在不考虑动画图片格式的前提下做前置压缩了

相关文档