I used wasm-bindgen to write a very basic JS/Wasm webapp in which a grayscale transformation (written in Rust) is applied to an image uploaded by the user of the webapp through an <input type="file"> and displayed in a <canvas>.
Doing so, I had to load the image in the WebAssembly memory space, apply the transformation on each pixel then return the result in the memory space for the JS to take care of the display:
import { memory} from "img-grayscale-wasm/img_grayscale_wasm_bg";
import {MyImage} from "img-grayscale-wasm"
//...
async function processImg(file, width, height){
const canvas = document.getElementById("pixel-grayscale");
var resp = await fetch(file.name)
var bytes = await resp.arrayBuffer()
const myImage = MyImage.new();
const ptr = myImage.alloc(bytes.byteLength);
// Copy to memory space
const imgArray = new Uint8Array(memory.buffer, ptr, bytes.byteLength);
imgArray.set(new Uint8Array(bytes));
// transform img
myImage.read_img(ptr, bytes.byteLength)
const grayScalePtr = myImage.to_grayscale(width, height)
// read from memory space
const arr = new Uint8ClampedArray(memory.buffer, grayScalePtr, width * height * 4);
let imageData = new ImageData(arr, width);
getContextFromCanvas(canvas, width, height).putImageData(imageData, 0, 0);
}
I think I can avoid the whole process of copying stuff back and forth to the memory space if I use the web's API binding defined in the web-sys crate, from fetching the file to the display of the grayscaled picture.
This is where I get confused: performance-wise, is there a gain in using web-sys and its web's API bindings instead of doing it all in JavaScript? Well, I suppose there is, but where is it?