h5web icon indicating copy to clipboard operation
h5web copied to clipboard

Save canvas as PNG without loss of resolution

Open axelboc opened this issue 5 years ago • 5 comments

Note that, in Firefox at least, there's a "View image" contextual option on the heatmap's canvas, which generates an image automatically. This doesn't work for me, but it works somewhat for others:

When I do "View image" with Firefox I see the zoomed image but then if leave go to another tab in firefox and go back to the image I see a empty (white) image. I get this URL: blob:null/b92087e5-f865-4a88-b13c-6c7b1481b192.

It may be worth making sure "View image" works before implementing a more advanced export feature.

axelboc avatar Apr 22 '20 09:04 axelboc

This is why View image rarely works: https://stackoverflow.com/a/15563621/758806 -- the rendering buffer is cleared soon after rendering for performance reasons.

axelboc avatar May 06 '20 11:05 axelboc

The screenshot button should generate an image with the same resolution as the dataset instead of just exporting the current rendering buffer of the canvas (the "View image" context menu action can still do that).

axelboc avatar May 12 '20 09:05 axelboc

I think this is a great use case for OffscreenCanvas - https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas. The idea would be to render the heatmap in a canvas the size of the data but off screen, in a web worker. It would then be trivial to generate a data URL from the canvas and open it a new tab like we do already.

I think this solution would be a lot cleaner than trying to generate a PNG manually from the texture data. Unfortunately, OffscreenCanvas is still behind a flag in Firefox. They intend to remove the flag this year, so I think it's worth waiting a bit.

EDIT: Firefox officially supports OffscreenCanvas since v105.

axelboc avatar May 18 '20 11:05 axelboc

With the OffscreenCanvas solution, we'll be able to remove the previous screenshot implementation, and therefore turn off preserveDrawingBuffer for performance reasons.

axelboc avatar Apr 16 '21 12:04 axelboc

Just to clarify that this issue is about generating a PNG image of the WebGL canvas as the user sees it (zoom level, color map, etc.), as opposed to #35, which was about exporting the raw dataset/slice as TIFF/NPY.

The challenge here is to generate a PNG without losing any resolution. The current "Snapshot" button only outputs an image with the size of the canvas as it is displayed on the screen. This is where OffscreenCanvas comes in: it should allow rendering a WebGL canvas offscreen with the exact dimensions of the dataset/slice to ensure we never generate a PNG with fewer pixels.

EDIT: R3F now seems to support rendering into an offscreen canvas: https://github.com/pmndrs/react-three-fiber/pull/2770

axelboc avatar Dec 03 '21 14:12 axelboc