基于顶级编解码器实现纯前端高效图片压缩
笔记哥 /
05-21 /
2点赞 /
0评论 /
987阅读

Google的Squoosh项目封装了MozJPEG、libwebp、rust Oxipng等顶级图像编解码器,但是使用依赖于Node.js,而jSquash项目对此进行了二次封装,将底层编解码器以WebAssembly的形式提供,实现不依赖node的纯前端的压缩方式。
经测试可以将10mb的png压缩为500kb的jpg,肉眼画质无损失,95%的优化。
文末会给出我的使用代码。github项目地址也在文末。
## jSquash
jSquash是一个轻量级、基于WebAssembly(WASM)的图像处理库,旨在为浏览器和V8运行时(如Cloudflare Workers)提供高效的图像编解码能力。其设计来源于Squoosh,强调浏览器兼容性和模块化。特点:
- 专注于浏览器和Web Worker,适合前端环境。
- 模块化设计:支持多种图像格式(如@jSquash/jpeg、@jSquash/png、@jSquash/webp等),按需引入。
- 无动态代码执行:可在严格环境中运行,如Cloudflare Workers。
而WASM优势:
- 接近原生代码的执行速度,适合计算密集型任务如图像压缩。
- 无需依赖特定运行时环境,浏览器即可运行。
- WASM运行在沙箱环境中,适合严格的执行环境。
比如@jSquash/jpeg使用MozJPEG库进行JPEG图像的编解码,@jSquash/webp基于libwebp实现WebP格式支持。通过Emscripten编译为WASM模块,并通过JavaScript接口暴露给开发者。
jSquash采用ES Module(ESM)格式,所有模块(如@jSquash/avif、@jSquash/png)均为独立包,可按需引入,减少了打包体积,适合Vite、Webpack这些前端构建工具。
jSquash也支持通过CDN直接使用(大陆环境不稳定):
```javascript
import { decode } from 'https://unpkg.com/@jsquash/jpeg?module';
```
## 处理流程:
1. 解码(Decode):将输入的图像二进制数据(ArrayBuffer)解码为原始RGB图像数据(ImageData)。例如,@jSquash/jpeg的decode方法将JPEG文件转换为ImageData对象。
2. 处理(可选):支持调整大小(@jSquash/resize)或优化(如@jSquash/oxipng)。调整大小支持多种算法(如Lanczos3、Magic Kernel)。
3. 编码(Encode):将处理后的ImageData编码为目标格式的二进制数据。例如,@jSquash/webp的encode方法生成WebP格式的ArrayBuffer。
jSquash的WASM模块通常由生成的胶水代码(glue code)自动初始化,支持大多数Web打包工具
## 图像格式支持
每种格式由独立的模块实现:
- @jSquash/avif - 使用 libavif 库的 AVIF 图像编码器和解码器
- @jSquash/jpeg - 使用 MozJPEG 库的 JPEG 图像编码器和解码器
- @jSquash/jxl - 使用 libjxl 库的 JPEG XL 图像编码器和解码器
- @jSquash/oxipng - 使用 Oxipng 的 PNG 图像优化器
- @jSquash/png - 使用 rust PNG crate 的 PNG 图像编解码器
- @jSquash/qoi - 使用官方库的 "相当好的图像格式" 编解码器
- @jSquash/resize - 使用 rust resize、hqx 和 magic-kernel 库的图像缩放工具。支持降缩和升缩。
- @jSquash/webp - 使用 libwebp 的 WebP 图像编码器和解码器
完整见官方readme,按需npm install即可(install的是@jsquash/xx而不是@jSquash/xx,要小写)。
## 代码
只包括图像处理的核心部分,图像是上传还是直接读取本地自行处理。
注意每个模块的使用方式是不一样的,比如oxipng的输入类型为arrayBuffer,而MozJpeg为imageData,具体需要查看每个封装模块的readme。
**jpeg、webp:**
这里encode可以传入配置quality,默认为75(0-100),具体库配置不同。png配置为level(1-6)
```js
import { decode } from '@jsquash/jpeg';
import { encode } from '@jsquash/webp';
async function convertToWebP(url) {
try {
const response = await fetch(url);
const imageBuffer = await response.arrayBuffer();
// 或者直接处理blob对象
// file.arrayBuffer()
const imageData = await decode(imageBuffer);
// 这里encode可以传入配置{ quality },默认为75(0-100),具体库配置不同。png配置为level(1-6)
const webpBuffer = await encode(imageData);
const blob = new Blob([webpBuffer], { type: 'image/webp' });
return URL.createObjectURL(blob);
} catch (error) {
console.error('转换失败:', error);
}
}
```
**rust oxipng:**
这里用canvas解码,因为这个库没提供解码函数。
```js
const bitmap = await createImageBitmap(file);
const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
const ctx = canvas.getContext('2d');
ctx.drawImage(bitmap, 0, 0);
const imageData = ctx.getImageData(0, 0, bitmap.width, bitmap.height);
bitmap.close();
return imageData;
```
*编码:*
```js
import {optimise as encodePNG} from '@jsquash/oxipng';
let buffer = await encodePNG(buffer, { level: 2 }),
return new Blob([buffer], {type: 'image/png'});
```
没有明确要求(比如png保留透明通道)的话建议输出格式转为jpeg,能大幅度减小体积。
## 注意
vite优化的时候要避开这些库,不能影响wasm,否则会导致无法生效:
```js
export default defineConfig({
optimizeDeps: {
exclude: ["@jsquash/jpeg", "@jsquash/oxipng", "@jsquash/webp"]
}
})
```
## 参考资料
- jSquash GitHub仓库:https://github.com/jamsinclair/jSquash
- Squoosh 项目:https://github.com/GoogleChromeLabs/squoosh
- WebAssembly 文档:https://webassembly.org/
- Emscripten 文档:https://emscripten.org/
本文来自投稿,不代表本站立场,如若转载,请注明出处:http//www.knowhub.vip/share/2/3552
- 热门的技术博文分享
- 1 . ESP实现Web服务器
- 2 . 从零到一:打造高效的金仓社区 API 集成到 MCP 服务方案
- 3 . 使用C#构建一个同时问多个LLM并总结的小工具
- 4 . .NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选
- 5 . 在Avalonia/C#中使用依赖注入过程记录
- 6 . [设计模式/Java] 设计模式之工厂方法模式
- 7 . 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
- 8 . SQL 中的各种连接 JOIN 的区别总结!
- 9 . JavaScript 中防抖和节流的多种实现方式及应用场景
- 10 . SaltStack 远程命令执行中文乱码问题
- 11 . 推荐10个 DeepSeek 神级提示词,建议搜藏起来使用
- 12 . C#基础:枚举、数组、类型、函数等解析
- 13 . VMware平台的Ubuntu部署完全分布式Hadoop环境
- 14 . C# 多项目打包时如何将项目引用转为包依赖
- 15 . Chrome 135 版本开发者工具(DevTools)更新内容
- 16 . 从零创建npm依赖,只需执行一条命令
- 17 . 关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题
- 18 . 大模型微调实战之训练数据集准备的艺术与科学
- 19 . Windows快速安装MongoDB之Mongo实战
- 20 . 探索 C# 14 新功能:实用特性为编程带来便利
- 相关联分享
- 基于顶级编解码器实现纯前端高效图片压缩