From a357a83860aaac90b37832de066e5a5a016910ea Mon Sep 17 00:00:00 2001
From: memdmp <memdmp@estrogen.zone>
Date: Wed, 25 Mar 2026 12:22:23 +0100
Subject: feat: figured i'd revisit this code i wrote as a shitpost, it seems
 quite decent actually

---
 src/lib/test/canvas/CanvasImg.svelte | 56 ++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)
 create mode 100644 src/lib/test/canvas/CanvasImg.svelte

(limited to 'src/lib/test/canvas/CanvasImg.svelte')

diff --git a/src/lib/test/canvas/CanvasImg.svelte b/src/lib/test/canvas/CanvasImg.svelte
new file mode 100644
index 0000000..ef9c870
--- /dev/null
+++ b/src/lib/test/canvas/CanvasImg.svelte
@@ -0,0 +1,56 @@
+<script lang="ts">
+  import { onDestroy } from 'svelte';
+  import { detect2dCanvasBlockOnCanvas } from './detect-canvas-block';
+
+  let { src, alt }: { src: string; alt: string } = $props();
+  let blobUrl = $state(undefined as undefined | string);
+
+  const blobify = async (image: HTMLImageElement) => {
+    if (!image.src.startsWith('blob:')) {
+      const canvas = document.createElement('canvas');
+      if (blobUrl) URL.revokeObjectURL(blobUrl);
+      const canvasOpts = {
+        desynchronized: true,
+        alpha: true,
+        willReadFrequently: false,
+        // change to unorm8 to use 8-bit colours (will break HDR images)
+        colorType: 'float16' as const,
+        // change to srgb if colours look off
+        colorSpace: 'display-p3' as const,
+      } as const;
+      const e = detect2dCanvasBlockOnCanvas(canvas, false, canvasOpts);
+      if (e) throw e;
+      try {
+        // See https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalHeight
+        const cw = (canvas.width = image.naturalWidth);
+        const ch = (canvas.height = image.naturalHeight);
+
+        const ctx = canvas.getContext('2d', canvasOpts)!;
+        ctx.drawImage(image, 0, 0, cw, ch);
+
+        blobUrl = URL.createObjectURL(
+          await new Promise<Blob>((rs, rj) =>
+            canvas.toBlob((value) =>
+              value ? rs(value) : rj(new Error('No blob')),
+            ),
+          ),
+        );
+      } catch (error) {
+        console.error('Failed to get canvas data:', error);
+      }
+    }
+  };
+
+  onDestroy(() => {
+    if (blobUrl) URL.revokeObjectURL(blobUrl);
+  });
+</script>
+
+<img
+  class="pointer-events-none"
+  loading="lazy"
+  src={blobUrl ?? src}
+  {alt}
+  onload={(e) =>
+    blobify((e.currentTarget ?? e.target) as unknown as HTMLImageElement)}
+/>
-- 
cgit v1.2.3

