Wasm Image Decoder
Decodes images using Rustâs image
crate compiled to WebAssembly. By default it uses 4 threads (though some decoders are single-threaded) since it doesnât seem to get much faster if I add any more. You can edit mod.js
to change the number of threads.
Works in the browser and in Deno.
Note: This can only be used within a Web Worker due to wasm not supporting blocking/waiting operations when executed in the main thread (related comment). You can use comlink
to make it easy to use this module from the main thread.
As of writing itâs about 3x slower than native Rust. Drawing the image to an OffscreenCanvas
and then extracting the image data is the same speed as native Rust, so use that if your JS runtime has it available. The communication overhead between JS and the wasm module is negligible, so the slowness is probably due to missing functionality and lack of optimisation in wasm runtimes (e.g. thread/simd/etc. optimisations), so the performance should improve with time.
File Formats Supported
It supports decoding PNG, JPEG, WEBP, GIF, BMP, ICO, TGA, and several others, but some formats donât have full support as of writing (Feb 2022). See here for the support table. Check the latest image-rs readme to see if there is increased support, and if so you can follow the build instructions below to build a version of this library that supports the new formats.
Demo
import decode from "https://deno.land/x/wasm_image_decoder@v0.0.5/mod.js";
let buf = await fetch("https://i.imgur.com/LYVUrUf.jpg", {referrer:""}).then(r => r.arrayBuffer()); // empty referrer header because imgur blocks requests from 127.0.0.1
let result = decode(buf);
console.log(result); // {width, height, data} where data is a Uint8Array array of RGBA values like [R,G,B,A,R,G,B,A,R,G,B,A,...]
Build
git clone https://github.com/josephrocca/wasm-image-decoder
cd wasm-image-decoder
cargo install wasm-pack
wasm-pack build --target=web --out-dir=wasm
Basic wasm-pack
tutorial here: https://developer.mozilla.org/en-US/docs/WebAssembly/Rust_to_wasm
If it fails with âunable to build with the standard libraryâ, youâll need to run
rustup component add rust-src