javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > 前端图片压缩

基于顶级编解码器实现纯前端高效图片压缩效果详解

作者:崩天的勾玉

Google的Squoosh项目封装了MozJPEG、libwebp、rust Oxipng等顶级图像编解码器,jSquash项目对此进行了二次封装,本文就来看看如何使用jSquash实现纯前端高效图片压缩效果吧

Google的Squoosh项目封装了MozJPEG、libwebp、rust Oxipng等顶级图像编解码器,但是使用依赖于Node.js,而jSquash项目对此进行了二次封装,将底层编解码器以WebAssembly的形式提供,实现不依赖node的纯前端的压缩方式。

经测试可以将10mb的png压缩为500kb的jpg,肉眼画质无损失,95%的优化。

jSquash

jSquash是一个轻量级、基于WebAssembly(WASM)的图像处理库,旨在为浏览器和V8运行时(如Cloudflare Workers)提供高效的图像编解码能力。其设计来源于Squoosh,强调浏览器兼容性和模块化。特点:

而WASM优势:

比如@jSquash/jpeg使用MozJPEG库进行JPEG图像的编解码,@jSquash/webp基于libwebp实现WebP格式支持。通过Emscripten编译为WASM模块,并通过JavaScript接口 暴露给开发者。

jSquash采用ES Module(ESM)格式,所有模块(如@jSquash/avif、@jSquash/png)均为独立包,可按需引入,减少了打包体积,适合Vite、Webpack这些前端构建工具。

jSquash也支持通过CDN直接使用(大陆环境不稳定):

import { decode } from 'https://unpkg.com/@jsquash/jpeg?module';

处理流程

jSquash的WASM模块通常由生成的胶水代码(glue code)自动初始化,支持大多数Web打包工具

图像格式支持

每种格式由独立的模块实现:

完整见官方readme,按需npm install即可(install的是@jsquash/xx而不是@jSquash/xx,要小写)。

代码

只包括图像处理的核心部分,图像是上传还是直接读取本地自行处理。
注意每个模块的使用方式是不一样的,比如oxipng的输入类型为arrayBuffer,而MozJpeg为imageData,具体需要查看每个封装模块的readme。

jpeg、webp:这里encode可以传入配置quality,默认为75(0-100),具体库配置不同。png配置为level(1-6)

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解码,因为这个库没提供解码函数。

      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;

编码:

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,否则会导致无法生效:

export default defineConfig({
    optimizeDeps: {
        exclude: ["@jsquash/jpeg", "@jsquash/oxipng", "@jsquash/webp"]
    }
})

到此这篇关于基于顶级编解码器实现纯前端高效图片压缩效果详解的文章就介绍到这了,更多相关前端图片压缩内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文