139 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<head>
 | 
						||
    <meta charset="utf-8">
 | 
						||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
						||
    <title>libwebp 压缩图片的 wasm 实现</title>
 | 
						||
</head>
 | 
						||
<body>
 | 
						||
    WebP 图:
 | 
						||
    <span>压缩:<span id="webpSize"></span></span>
 | 
						||
    <img id="webpImage" alt="WebP Image">
 | 
						||
    <br>
 | 
						||
    <br>
 | 
						||
    <input type="file" id="imageUpload" accept="image/*" onchange="handleFileUpload(event)">
 | 
						||
    <br>
 | 
						||
    <label for="width">宽度:</label>
 | 
						||
    <input type="number" id="width" value="0">
 | 
						||
    <br>
 | 
						||
    <label for="height">高度:</label>
 | 
						||
    <input type="number" id="height" value="0">
 | 
						||
    <br>
 | 
						||
    <label for="quality">质量:</label>
 | 
						||
    <input type="number" id="quality" value="50" min="0" max="100">
 | 
						||
    <br>
 | 
						||
    <div id="result"></div>
 | 
						||
</body>
 | 
						||
 | 
						||
<script>
 | 
						||
    function base64ToArrayBuffer(base64) {
 | 
						||
        var binaryString = atob(base64);
 | 
						||
        var len = binaryString.length;
 | 
						||
        var bytes = new Uint8Array(len);
 | 
						||
        for (var i = 0; i < len; i++) {
 | 
						||
            bytes[i] = binaryString.charCodeAt(i);
 | 
						||
        }
 | 
						||
        // 返回 ArrayBuffer
 | 
						||
        return bytes.buffer;
 | 
						||
    }
 | 
						||
    // 将 WASM 生成的二进制数据转换成 Base64
 | 
						||
    function arrayBufferToBase64(buffer) {
 | 
						||
        let binary = '';
 | 
						||
        let len = buffer.byteLength;
 | 
						||
        for (let i = 0; i < len; i++) {
 | 
						||
            binary += String.fromCharCode(buffer[i]);
 | 
						||
        }
 | 
						||
        return btoa(binary);  // 使用 JavaScript 的 btoa() 函数
 | 
						||
    }
 | 
						||
 | 
						||
    var fileurl = './image.png'
 | 
						||
    // 初始化 WebAssembly 模块
 | 
						||
    var Module = {
 | 
						||
        onRuntimeInitialized: function () {
 | 
						||
 | 
						||
            //    let baseData= document.getElementById("base64Image").src;
 | 
						||
            //    baseData=baseData.split(",")[1];
 | 
						||
            //    let buffer = base64ToArrayBuffer(baseData);
 | 
						||
            //        decodeToWebpp(buffer);
 | 
						||
            // document.getElementById("base64Image").src = fileurl;
 | 
						||
            decodeIt();
 | 
						||
 | 
						||
        },
 | 
						||
        onAbort:(e)=>{
 | 
						||
            alert(e);
 | 
						||
        }
 | 
						||
    };
 | 
						||
    function clickIt(ti=4){
 | 
						||
        for(var i=0;i<ti;i++){
 | 
						||
            decodeIt(`./${i+1}.jpg`);
 | 
						||
        }
 | 
						||
    }
 | 
						||
    var startTime=0;
 | 
						||
    function decodeIt(url) {
 | 
						||
        if (!url) {
 | 
						||
            url = fileurl;
 | 
						||
        }
 | 
						||
        fetch(url).then(response => response.arrayBuffer()).then(buffer => {
 | 
						||
            startTime=Date.now();
 | 
						||
            decodeToWebpp(buffer);
 | 
						||
        })
 | 
						||
    }
 | 
						||
 | 
						||
    function handleFileUpload(event) {
 | 
						||
        const file = event.target.files[0];
 | 
						||
        if (file) {
 | 
						||
            const reader = new FileReader();
 | 
						||
            reader.onload = function(e) {
 | 
						||
                const buffer = base64ToArrayBuffer(e.target.result.split(",")[1]);
 | 
						||
                const targetWidth = document.getElementById("width").value;
 | 
						||
                const targetHeight = document.getElementById("height").value;
 | 
						||
                const qualityFactor = document.getElementById("quality").value;
 | 
						||
                decodeToWebpp(buffer,targetWidth,targetHeight,qualityFactor);
 | 
						||
            };
 | 
						||
            reader.readAsDataURL(file);
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 将图片转换为 WebP 格式
 | 
						||
     * @param {ArrayBuffer} buffer - 图片的二进制数据
 | 
						||
     * @param {number} targetWidth - 目标宽度
 | 
						||
     * @param {number} targetHeight - 目标高度
 | 
						||
     * @param {number} qualityFactor - 压缩质量 (0 - 100)
 | 
						||
     */
 | 
						||
    function decodeToWebpp(buffer,targetWidth=0,targetHeight=0,qualityFactor=50) {
 | 
						||
        // 显示原始图片大小
 | 
						||
        let size = (buffer.byteLength / 1024).toFixed(2);
 | 
						||
 | 
						||
        // 转换图像为 Uint8Array
 | 
						||
        var inputData = new Uint8Array(buffer);
 | 
						||
 | 
						||
        // 分配内存以存储输出 WebP 大小
 | 
						||
        var outputSizePtr = Module._malloc(4); // 存储输出大小的指针
 | 
						||
 | 
						||
        // 设置目标宽高和质量因子
 | 
						||
        var inputDataPtr = Module._malloc(inputData.length);
 | 
						||
        Module.HEAPU8.set(inputData, inputDataPtr);
 | 
						||
        var webpPtr = Module._convert_image_to_webp(inputDataPtr, inputData.length, targetWidth, targetHeight, qualityFactor, outputSizePtr);
 | 
						||
      
 | 
						||
        // 调用 WebAssembly 函数进行图像转换,返回 WebP 数据指针
 | 
						||
 | 
						||
        // 获取 WebP 数据大小
 | 
						||
        var outputSize = Module.getValue(outputSizePtr, 'i32');
 | 
						||
 | 
						||
        // 从 WebAssembly 内存中读取 WebP 数据
 | 
						||
        var webpData = new Uint8Array(Module.HEAPU8.buffer, webpPtr, outputSize);
 | 
						||
        document.getElementById('result').innerText+='      '+(Date.now()-startTime) +'ms';
 | 
						||
 | 
						||
        // 显示 WebP 图片大小
 | 
						||
        document.getElementById("webpSize").textContent =`${size}KB => ${(outputSize / 1024).toFixed(2)}KB`;
 | 
						||
 | 
						||
        // 将 WebP 数据转换为 base64,并显示
 | 
						||
        let img = document.getElementById("webpImage");
 | 
						||
        img.src = "data:image/webp;base64," + arrayBufferToBase64(webpData);
 | 
						||
 | 
						||
        // 使用完成后释放内存
 | 
						||
        Module._free(outputSizePtr);
 | 
						||
        Module._free(webpPtr);
 | 
						||
        Module._free(inputDataPtr);
 | 
						||
    }
 | 
						||
</script>
 | 
						||
<script src="convert_image_to_webp.js"></script> |