libwebp-compress/utils(小程序兼容代码).js
2025-11-27 15:32:16 +08:00

131 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// wasm图片压缩工具类
const wasmMgr = {
// 存储已加载的wasm模块
imageCompressModule: null,
// 获取图片压缩模块
getCompressImg() {
if (this.imageCompressModule) {
return Promise.resolve(this.imageCompressModule);
}
return new Promise((resolve, reject) => {
const wasmImports = {
__assert_fail: (condition, filename, line, func) => {
console.log(condition, filename, line, func);
},
emscripten_resize_heap: (size, old_size) => {
console.log(size, old_size);
},
fd_close: (fd) => {
console.log(fd);
},
fd_seek: (fd, offset, whence) => {
console.log(fd, offset, whence);
},
fd_write: (fd, buf, len, pos) => {
console.log(fd, buf, len, pos);
},
emscripten_memcpy_js: (dest, src, len) => {
this.imageCompressModule.HEAPU8.copyWithin(dest, src, src + len);
},
};
// 微信小程序环境
if (typeof WXWebAssembly !== "undefined") {
WXWebAssembly.instantiate(
"/convert_image_to_webp.wasm",
{
env: wasmImports,
wasi_snapshot_preview1: wasmImports,
}
).then((result) => {
this.imageCompressModule = {
_convert_image_to_webp: result.instance.exports.convert_image_to_webp,
_malloc: result.instance.exports.malloc,
_free: result.instance.exports.free,
};
this.imageCompressModule.HEAPU8 = new Uint8Array(
result.instance.exports.memory.buffer
);
console.log("convert_image_to_webp加载成功");
resolve(this.imageCompressModule);
}).catch((err) => {
console.error("Failed to load wasm script", err);
reject(err);
});
} else {
// H5环境或其他环境
console.error("当前环境不支持WebAssembly");
reject(new Error("当前环境不支持WebAssembly"));
}
});
},
// 图片压缩函数
async compressImg(file, quality = 0.5, w, h, target_w, target_h) {
const compressImgHandler = (inputData, module, isOrgin = false) => {
const inputDataPtr = module._malloc(inputData.length);
module.HEAPU8.set(inputData, inputDataPtr);
const outputSizePtr = module._malloc(4);
const webpPtr = module._convert_image_to_webp(
inputDataPtr,
inputData.length,
w,
h,
target_w,
target_h,
80 * (quality > 1 ? 1 : quality),
outputSizePtr,
1,
isOrgin ? 1 : 0
);
const outputSize =
module.HEAPU8[outputSizePtr] |
(module.HEAPU8[outputSizePtr + 1] << 8) |
(module.HEAPU8[outputSizePtr + 2] << 16) |
(module.HEAPU8[outputSizePtr + 3] << 24);
const webpData = new Uint8Array(module.HEAPU8.buffer, webpPtr, outputSize);
module._free(webpPtr);
module._free(outputSizePtr);
module._free(inputDataPtr);
//如果只需要二进制原始数据可以直接返回webpdata 减少base64转换
// return webpData
return 'data:image/webp;base64,' + this.arrayBufferToBase64(webpData);
};
try {
const module = await this.getCompressImg();
if (file instanceof Uint8Array) {
return compressImgHandler(file, module, true);
} else {
return new Promise((resolve, reject) => {
wx.getFileSystemManager().readFile({
filePath: file,
success: res => {
resolve(compressImgHandler(new Uint8Array(res.data), module));
},
fail: e => {
console.error("读取文件失败", e);
reject(e);
},
});
});
}
} catch (error) {
console.error("图片压缩失败", error);
throw error;
}
},
// 将ArrayBuffer转换为Base64
arrayBufferToBase64(buffer) {
return wx.arrayBufferToBase64(buffer);
}
};
module.exports = {
wasmMgr
};