/** * Downscale an image file to a thumbnail and return an object URL. * Returns undefined for non-image files. * Caller is responsible for revoking the URL via URL.revokeObjectURL(). */ export async function createImageThumbnail( file: File, maxDim = 200, ): Promise { if (!file.type.startsWith("image/")) return undefined; const bitmap = await createImageBitmap(file); const scale = Math.min(1, maxDim / Math.max(bitmap.width, bitmap.height)); const w = Math.round(bitmap.width * scale); const h = Math.round(bitmap.height * scale); const canvas = new OffscreenCanvas(w, h); const ctx = canvas.getContext("2d")!; ctx.drawImage(bitmap, 0, 0, w, h); bitmap.close(); const blob = await canvas.convertToBlob({ type: "image/jpeg", quality: 0.7 }); return URL.createObjectURL(blob); }