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 should work in Deno when this PR lands and 1.10.0 is released (around May 2021).

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 (April 2021). 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.4/mod.js";
let buf = await fetch("https://i.imgur.com/LYVUrUf.jpg").then(r => r.arrayBuffer());
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