/ concept-collection / numbl-image-filter
Sign in
concept-collection / numbl-image-filter
numbl-image-filter / src / imageLoad.ts
84 lines · 2.6 KBBlameHistoryRaw
1/** Loading and rasterizing images to RGBA byte arrays. */
2import type { RawImage } from "./imageConvert.ts";
4function drawableToRaw(
5 source: CanvasImageSource,
6 width: number,
7 height: number
8): RawImage {
9 const canvas = document.createElement("canvas");
10 canvas.width = width;
11 canvas.height = height;
12 const ctx = canvas.getContext("2d", { willReadFrequently: true });
13 if (!ctx) throw new Error("Could not get a 2D canvas context.");
14 ctx.drawImage(source, 0, 0, width, height);
15 const imageData = ctx.getImageData(0, 0, width, height);
16 return { width, height, rgba: imageData.data };
19/** Load an image from an uploaded File / Blob. */
20export async function loadImageFromFile(file: Blob): Promise<RawImage> {
21 const bitmap = await createImageBitmap(file);
22 try {
23 return drawableToRaw(bitmap, bitmap.width, bitmap.height);
24 } finally {
25 bitmap.close();
26 }
29/** Render a RawImage onto a canvas element (sizing it to match). */
30export function drawRawToCanvas(
31 canvas: HTMLCanvasElement,
32 raw: RawImage
33): void {
34 canvas.width = raw.width;
35 canvas.height = raw.height;
36 const ctx = canvas.getContext("2d");
37 if (!ctx) return;
38 ctx.putImageData(
39 new ImageData(new Uint8ClampedArray(raw.rgba), raw.width, raw.height),
40 0,
41 0
42 );
45/** Encode a RawImage to a PNG data URL (used for the download button). */
46export function rawToDataUrl(raw: RawImage): string {
47 const canvas = document.createElement("canvas");
48 canvas.width = raw.width;
49 canvas.height = raw.height;
50 const ctx = canvas.getContext("2d");
51 if (!ctx) throw new Error("Could not get a 2D canvas context.");
52 ctx.putImageData(
53 new ImageData(new Uint8ClampedArray(raw.rgba), raw.width, raw.height),
54 0,
55 0
56 );
57 return canvas.toDataURL("image/png");
60/** Encode a small (longest side = max px) JPEG thumbnail data URL. */
61export function rawToThumbDataUrl(raw: RawImage, max = 72): string {
62 const scale = Math.min(1, max / Math.max(raw.width, raw.height));
63 const w = Math.max(1, Math.round(raw.width * scale));
64 const h = Math.max(1, Math.round(raw.height * scale));
66 const src = document.createElement("canvas");
67 src.width = raw.width;
68 src.height = raw.height;
69 src
70 .getContext("2d")!
71 .putImageData(
72 new ImageData(new Uint8ClampedArray(raw.rgba), raw.width, raw.height),
73 0,
74 0
75 );
77 const dst = document.createElement("canvas");
78 dst.width = w;
79 dst.height = h;
80 const ctx = dst.getContext("2d");
81 if (!ctx) throw new Error("Could not get a 2D canvas context.");
82 ctx.drawImage(src, 0, 0, w, h);
83 return dst.toDataURL("image/jpeg", 0.7);
moveopenescclose