WebShell中实现前端图片压缩

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

MIME

media type

1
<input type="file" id="selectImg" accept="image/*"/>
  1. 比如图片上传选择框进行限制,非图片类不可选,则可以使用image/*
  2. 该限制比如在Windows下可以被绕开,因此在提交逻辑/后端还可以再严格限制下,方案也是通过mime
1
2
3
4
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

1
2
3
4
5
<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,从而确定显示对应图片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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. 前端在不考虑动画图片格式的前提下做前置压缩了

相关文档