Created
December 23, 2025 10:29
-
-
Save greggman/2359aec968f72ec4b24f69c712753d59 to your computer and use it in GitHub Desktop.
Load Image with Alpha (via Image)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| :root { | |
| color-scheme: dark light; | |
| } | |
| canvas { | |
| background-color: #404040; | |
| background-image: | |
| linear-gradient(45deg, #808080 25%, transparent 25%), | |
| linear-gradient(-45deg, #808080 25%, transparent 25%), | |
| linear-gradient(45deg, transparent 75%, #808080 75%), | |
| linear-gradient(-45deg, transparent 75%, #808080 75%); | |
| background-size: 32px 32px; | |
| background-position: 0 0, 0 16px, 16px -16px, -16px 0px; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*bug-in-github-api-content-can-not-be-empty*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| async function readPNG_RGBA(url) { | |
| // 1. Init WebGPU | |
| const adapter = await navigator.gpu.requestAdapter(); | |
| const device = await adapter.requestDevice(); | |
| // 2. Fetch + decode PNG (NO color conversion, NO premultiply) | |
| const bmp = new Image(); | |
| bmp.crossOrigin = ''; | |
| bmp.src = url; | |
| await bmp.decode(); | |
| const w = bmp.width; | |
| const h = bmp.height; | |
| // 3. Create texture | |
| const texture = device.createTexture({ | |
| size: [w, h], | |
| format: "rgba8unorm-srgb", | |
| usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC | GPUTextureUsage.RENDER_ATTACHMENT | |
| }); | |
| // 4. Upload bitmap to texture | |
| device.queue.copyExternalImageToTexture( | |
| { source: bmp }, | |
| { texture }, | |
| [w, h] | |
| ); | |
| // 5. Create readback buffer | |
| const bytesPerRow = ((w * 4 + 255) & ~255); // WebGPU row alignment | |
| const buffer = device.createBuffer({ | |
| size: bytesPerRow * h, | |
| usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ | |
| }); | |
| // 6. Copy texture → buffer | |
| const encoder = device.createCommandEncoder(); | |
| encoder.copyTextureToBuffer( | |
| { texture }, | |
| { buffer, bytesPerRow }, | |
| [w, h] | |
| ); | |
| device.queue.submit([encoder.finish()]); | |
| // 7. Map + read data | |
| await buffer.mapAsync(GPUMapMode.READ); | |
| const mapped = new Uint8Array(buffer.getMappedRange()); | |
| console.log("Top-left RGBA:", mapped[0], mapped[1], mapped[2], mapped[3]); | |
| // draw it to a canvas | |
| const canvas = document.createElement('canvas'); | |
| const context = canvas.getContext('webgpu'); | |
| context.configure({ | |
| device, | |
| format: 'rgba8unorm', | |
| usage: GPUTextureUsage.COPY_DST, | |
| alphaMode: 'premultiplied', | |
| }); | |
| canvas.width = w; | |
| canvas.height = w; | |
| document.body.appendChild(canvas); | |
| { | |
| const canvasTexture = context.getCurrentTexture(); | |
| const encoder = device.createCommandEncoder(); | |
| encoder.copyTextureToTexture( | |
| { texture }, | |
| { texture: canvasTexture }, | |
| [w, h], | |
| ); | |
| device.queue.submit([encoder.finish()]); | |
| } | |
| } | |
| readPNG_RGBA("https://greggman.github.io/doodles/images/FurBaseColorAlpha.png"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {"name":"Load Image with Alpha (via Image)","settings":{},"filenames":["index.html","index.css","index.js"]} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment