Img2Num UMD Example Application
A simple demo app showing how to use Img2Num's JavaScript library as an AMD module. RequireJS loads the UMD build from lib/, so nothing is added to the global scope.
Upload an image to convert it to an SVG.
A simple demo app showing how to use Img2Num's JavaScript library as an AMD module. RequireJS loads the UMD build from lib/, so nothing is added to the global scope.
Upload an image to convert it to an SVG.
Load the library from a CDN (UMD format) — this page ships its own copy in lib/ so it also works offline:
<label id="dropZone" class="dropzone" for="fileInput" tabindex="0">
<span id="uploadHelp">Drag & drop an image here, paste one (Ctrl+V), or </span>
<input
type="file"
id="fileInput"
aria-describedby="uploadHelp"
accept=".png,.jpg,.jpeg,.gif,.bmp,.webp,.avif,image/png,image/jpeg,image/gif,image/bmp,image/webp,image/avif"
/>
</label>
<img id="originalImg" alt="" />
<div id="spinner" class="spinner"></div>
<img id="previewImg" alt="" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/require.js"></script>
<script>
requirejs.config({ paths: { img2num: "https://cdn.jsdelivr.net/npm/[email protected]/dist/standalone/img2num.umd" } });
requirejs(["img2num"], ({ imageToUint8ClampedArray, imageToSvg }) => {
const fileInput = document.getElementById("fileInput");
const dropZone = document.getElementById("dropZone");
const originalImg = document.getElementById("originalImg");
const previewImg = document.getElementById("previewImg");
const spinner = document.getElementById("spinner");
let latestRequest = 0;
async function processImage(file) {
if (!file || !file.type.startsWith("image/")) return;
const request = ++latestRequest;
if (originalImg.src.startsWith("blob:")) {
URL.revokeObjectURL(originalImg.src);
}
originalImg.src = URL.createObjectURL(file);
previewImg.removeAttribute("src");
spinner.style.display = "block";
try {
const { pixels, width, height } = await imageToUint8ClampedArray(file);
const { svg } = await imageToSvg({ pixels, width, height });
if (request !== latestRequest) return;
previewImg.src = "data:image/svg+xml;base64," + btoa(svg);
} catch (error) {
console.error("Failed to convert image:", error);
if (request === latestRequest) {
alert("An error occurred.\nCheck the developer console for details.");
}
} finally {
if (request === latestRequest) spinner.style.display = "none";
// Note: terminateWasmModule() is deliberately NOT called here. It frees
// the WASM resources, which would force a full re-initialization on the
// next conversion. Cleanup happens automatically on page teardown.
}
}
// File picker
fileInput.addEventListener("change", (e) => processImage(e.target.files[0]));
// Paste (Ctrl+V)
document.addEventListener("paste", (e) => {
const item = [...e.clipboardData.items].find((i) => i.type.startsWith("image/"));
if (item) processImage(item.getAsFile());
});
// Drag & drop
dropZone.addEventListener("dragover", (e) => {
e.preventDefault();
dropZone.classList.add("dropzone--active");
});
dropZone.addEventListener("dragleave", () => {
dropZone.classList.remove("dropzone--active");
});
dropZone.addEventListener("drop", (e) => {
e.preventDefault();
dropZone.classList.remove("dropzone--active");
const file = [...e.dataTransfer.files].find((f) => f.type.startsWith("image/"));
if (file) processImage(file);
});
// Keyboard (Enter/Space on the focused drop zone)
dropZone.addEventListener("keydown", (e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
fileInput.click();
}
});
});
</script>
Or install it locally: npm install img2num — see the installation guide.
Full page source is viewable with your browser's View Source — it's a complete, standalone app. See the usage guide for options like
num_colors and the bilateral filter parameters.