I am trying for some time now to convert a Canvas into a base64 image String, so I am able to convert it back later to show on the screen or store it in a file.
The problem is, all samples I found so far use SwingFXUtils.fromFXImage() or other AWT related classes.
The application I build will use the Gluon Substrate compiler to create mobile apps, which don't support all these classes. So is there a way to do this without any AWT/Swing related classes?
I get as far as this, resulting in an application/octet-stream, but I need an image mime type:
Canvas _canvas;
WritableImage image = new WritableImage((int) _canvas.getWidth(), (int) _canvas.getHeight());
_canvas.snapshot(new SnapshotParameters(), image);
int w = (int) image.getWidth();
int h = (int) image.getHeight();
byte[] buf = new byte[w * h * 4];
image.getPixelReader().getPixels(0, 0, w, h, PixelFormat.getByteBgraInstance(), buf, 0, w * 4);
String base64_image = McUtils.toBase64(buf);
You can encode the pixel data as a bitmap, then encode the bitmap data as a base64 encoded image data uri.
image/bmpBase64 encoding applicationThe bmp encoding algorithm was adapted from this algorithm by Philipp C. Heckel
BmpEncoderApp.java
BmpUriEncoder.java
Generated base 64 encoded image data URI
You can copy the resultant data uri and paste it into a browser navigation bar and the browser will display the snapshot image.
A couple of notes on this BMP implementation
BI_BITFIELDSformat as demoed in the wikipedia article on the BMP format. I tried that, but it didn't render correctly. I am not sure if that was due to an error in my encoding attempt or if support for such a format in standard renderers is limited.If alpha channel support is required, I advise encoding to a png (for which I provide no solution) rather than using the bmp format, as png alpha channel support will be more reliable in potential client applications.
Encoding to other formats (png or jpg)
Usage of different formats that handle compression, such as png or jpg might be preferred for some tasks. For instance jpg is good for encoding photographic images in a small size and png is good at lossless compression with alpha channel support. But jpg and png are more complex to encode then a bmp format. If you wished to support the more advanced image formats, I suggest adapting an appropriate image encoder library to encode the data extracted from the JavaFX pixel writer.