/** Loading and rasterizing images to RGBA byte arrays. */ import type { RawImage } from "./imageConvert.ts"; function drawableToRaw( source: CanvasImageSource, width: number, height: number ): RawImage { const canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; const ctx = canvas.getContext("2d", { willReadFrequently: true }); if (!ctx) throw new Error("Could not get a 2D canvas context."); ctx.drawImage(source, 0, 0, width, height); const imageData = ctx.getImageData(0, 0, width, height); return { width, height, rgba: imageData.data }; } /** Load an image from an uploaded File / Blob. */ export async function loadImageFromFile(file: Blob): Promise { const bitmap = await createImageBitmap(file); try { return drawableToRaw(bitmap, bitmap.width, bitmap.height); } finally { bitmap.close(); } } /** Render a RawImage onto a canvas element (sizing it to match). */ export function drawRawToCanvas( canvas: HTMLCanvasElement, raw: RawImage ): void { canvas.width = raw.width; canvas.height = raw.height; const ctx = canvas.getContext("2d"); if (!ctx) return; ctx.putImageData( new ImageData(new Uint8ClampedArray(raw.rgba), raw.width, raw.height), 0, 0 ); } /** Encode a RawImage to a PNG data URL (used for the download button). */ export function rawToDataUrl(raw: RawImage): string { const canvas = document.createElement("canvas"); canvas.width = raw.width; canvas.height = raw.height; const ctx = canvas.getContext("2d"); if (!ctx) throw new Error("Could not get a 2D canvas context."); ctx.putImageData( new ImageData(new Uint8ClampedArray(raw.rgba), raw.width, raw.height), 0, 0 ); return canvas.toDataURL("image/png"); } /** Encode a small (longest side = max px) JPEG thumbnail data URL. */ export function rawToThumbDataUrl(raw: RawImage, max = 72): string { const scale = Math.min(1, max / Math.max(raw.width, raw.height)); const w = Math.max(1, Math.round(raw.width * scale)); const h = Math.max(1, Math.round(raw.height * scale)); const src = document.createElement("canvas"); src.width = raw.width; src.height = raw.height; src .getContext("2d")! .putImageData( new ImageData(new Uint8ClampedArray(raw.rgba), raw.width, raw.height), 0, 0 ); const dst = document.createElement("canvas"); dst.width = w; dst.height = h; const ctx = dst.getContext("2d"); if (!ctx) throw new Error("Could not get a 2D canvas context."); ctx.drawImage(src, 0, 0, w, h); return dst.toDataURL("image/jpeg", 0.7); }