import React from "react"; import "./App.css"; function App() { const [imageSrc, setImageSrc] = React.useState(""); const fileInput = React.useRef(null); const handleClick = async () => { if (!fileInput.current) { return; } const workerProxy: any = await wasmWorker("main.wasm"); setImageSrc(""); // Check if a file was selected if (fileInput.current.files!.length === 0) { alert("No file selected"); return; } const reader = new FileReader(); reader.readAsArrayBuffer(fileInput.current.files![0]); reader.onloadend = async (evt) => { if (evt.target!.readyState === FileReader.DONE) { const imageData = new Uint8Array(evt.target!.result as ArrayBuffer); const ditheredImageArray = await workerProxy.DitherNord(imageData); const imageBlob = new Blob([ditheredImageArray.buffer], { type: "image/png", }); const url = URL.createObjectURL(imageBlob); setImageSrc(url); } }; }; return (
dithering output
); } function wasmWorker(modulePath: string) { // Create an object to later interact with const proxy: any = {}; // Keep track of the messages being sent // so we can resolve them correctly let id = 0; let idPromises: any = {}; return new Promise((resolve, reject) => { const worker = new Worker("./worker.js"); worker.postMessage({ eventType: "INITIALISE", eventData: modulePath }); worker.addEventListener("message", function (event: any) { const { eventType, eventData, eventId } = event.data; if (eventType === "INITIALISED") { const methods = event.data.eventData; methods.forEach((method: any) => { proxy[method] = (...args: any[]) => { return new Promise((resolve, reject) => { worker.postMessage({ eventType: "CALL", eventData: { method: method, arguments: Array.from(args), }, eventId: id, }); idPromises[id] = { resolve, reject }; id++; }); }; }); resolve(proxy); return; } else if (eventType === "RESULT") { if (eventId !== undefined && idPromises[eventId]) { idPromises[eventId].resolve(eventData); delete idPromises[eventId]; } } else if (eventType === "ERROR") { if (eventId !== undefined && idPromises[eventId]) { idPromises[eventId].reject(event.data.eventData); delete idPromises[eventId]; } } }); worker.addEventListener("error", function (error: any) { reject(error); }); }); } export default App;