iOS 图片优化之 webp 图片解码简单 demo
利用 WebAssembly 解决 WKwebview 宿主 iOS Safira 不支持解析 webp 的问题
先看 ios13.2.3 safari 解码 webp
图片与不使用 webp 编码加载时间对比
demo 中 webp_wasm.wasm
文件于 js 胶水
文件 webp_wasm.js
可通过 github 谷歌 libwebp
开源项目 readme的指引编译
二话不说直接上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WASM demo of WebP decoding</title>
<script type="text/javascript">
var Module = {
noInitialRun : true
};
</script>
<script type="text/javascript">
function init() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'webp_wasm.wasm', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
Module.wasmBinary = xhr.response;
var script = document.createElement('script');
script.src = "webp_wasm.js";
document.body.appendChild(script);
};
xhr.send(null);
}
function decode(webp_data, canvas_id) {
var result;
if (Module["asm"] != undefined) {
// wrapper for the function decoding a WebP into a canvas object
WebpToCanvas = Module.cwrap('WebpToSDL', 'number', ['array', 'number']);
// get the canvas to decode into
// var canvas = document.getElementById(canvas_id);
canvas = document.createElement('canvas');
if (canvas == null) return;
// clear previous picture (if any)
Module.canvas = canvas;
ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
// decode and measure timing
start = new Date();
var ret = WebpToCanvas(webp_data, webp_data.length); // webp 图像像素写入canvas
console.log(ret);
base64 = canvas.toDataURL("image/png");
document.getElementById('decode_base64').src = base64;
end = new Date();
var decode_time = end - start;
result = 'decoding time: ' + decode_time +' ms.';
} else {
result = "WASM module not finished loading! Please retry";
}
// display timing result
speed_result = document.getElementById('timing');
if (speed_result != null) {
speed_result.innerHTML = '<p>'+ result + '</p>';
}
}
function loadfile(filename, canvas_id) {
var xhr = new XMLHttpRequest();
xhr.open('GET', filename);
xhr.responseType = 'arraybuffer';
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var webp_data = new Uint8Array(xhr.response);
decode(webp_data, canvas_id);
}
};
xhr.send();
}
function loadImage(filename,img_id,time_id){
var img = new Image();
var start = new Date();
var speed_result2 = document.getElementById(time_id);
img.onload = function(){
// display timing result
if (speed_result2 != null) {
document.getElementById('output_webp_img').appendChild(img);
var end = new Date();
var decode_time = end - start;
speed_result2.innerHTML = '<p>'+time_id+' decoding time: ' + decode_time +' ms.</p>';
}
}
img.src = filename;
}
</script>
</head>
<body onload='init()' bgcolor='#f0f8ff'>
<p>
<strong>WebP demo using <a href="http://webassembly.org/">Web-Assembly</a></strong> -
</p>
<p>
WASM version of the WebP decoder, using <a
href="https://github.com/webmproject/libwebp">libwebp</a> compiled with
<a href="https://github.com/kripken/emscripten/wiki">Emscripten</a>.
</p>
<p>
<br/>
Requires a <a href="https://developer.mozilla.org/en-US/docs/WebAssembly#Browser_compatibility">native-wasm
enabled browser</a> (Chrome M58, WebKit)
<br/>
</p>
<p id="image_buttons">
<input type="button" value="lossy example" name="//img.alicdn.com/bao/uploaded/i4/2549599360/O1CN01YZ4MJz2J0vkikfMTT_!!0-item_pic.jpg_.webp"
onclick="loadfile(this.name, 'output_canvas')">
<input type="button" value="lossy+alpha example" name="./test2.webp"
onclick="loadfile(this.name, 'output_canvas')">
<input type="button" value="lossless example" name="./test3.webp"
onclick="loadfile(this.name, 'output_canvas')">
<input type="button" value="img load" onclick="loadImage(this.name,'output_webp_img','b_load_img')" name="//img.alicdn.com/bao/uploaded/i4/2549599360/O1CN01YZ4MJz2J0vkikfMTT_!!0-item_pic.jpg">
<input type="button" onclick="loadImage(this.name,'output_webp_img','b_load_webp_img')" value="img webp load" name="//img.alicdn.com/bao/uploaded/i4/2549599360/O1CN01YZ4MJz2J0vkikfMTT_!!0-item_pic.jpg_b.jpg_.webp">
</p>
<p id="timing">Timing: N/A</p>
<p id="load_decode_time"></p>
<p id="b_load_webp_img"></p>
<p id="b_load_img"></p>
<div id="output_webp_img"></div>
<canvas id="output_canvas">Your browser does not support canvas</canvas>
<img id="decode_base64">
</body>
</html>