// 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 };