diff options
feat: figured i'd revisit this code i wrote as a shitpost, it seems quite decent actually
Diffstat (limited to 'src/lib/test/canvas/CanvasImg.svelte')
| -rw-r--r-- | src/lib/test/canvas/CanvasImg.svelte | 56 |
1 files changed, 56 insertions, 0 deletions
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)} +/> |