I'm searching for a good method to upload a canvas element from Firefox to a webserver or database to have the ability to reload it later.
My ideas:
1. my first idea was to use getImageData() and save the canvas as an ImageData object to the database, but this might not a good solution because these objets can get quite large.
2. second idea is to use a Flash/Javascript method to upload the canvas as an PNG to the webserver.
Do you have any comments on these methods or maybe have another good solution?
Canvas elements have a toDataURL function that serializes the image on the canvas as a PNG, encoded into a data URL. You could either post the image with a form (by setting a hidden input element's value to the data URL) or in the background using AJAX.
You should be aware that toDataURL (or any other method of getting the pixel data) will throw a security exception if the canvas is not "origin-clean". For example, if you ever call drawImage with an image from a different domain, you can no longer use the toDataURL or getImageData functions.
I'm not too sure I would be worried about size unless images are typically > 10 mb in size. Is that really an issue?
If not, using getImageData() would be the most practical and simplest method IMO.
Related
I need to compress and rotate the image in the browser. Image sources can be drag'n'drop from a local user or the image can be downloaded from an URL with the same domain as the page with this script. But asking for permission to use HTML5 canvas doesn't fit into the design specification in any way.
The image can be in JPEG, PNG or HEIC format and in the current implementation is stored in Uint8Array. Is it possible to generate a thumbnail or change image orientation without using canvas?
No browser that I know of will ask for permission to use a canvas. Using a canvas is the quickest solution to do this (it's very simple indeed), and HEIC support is easy too: https://alexcorvi.github.io/heic2any/
When I load SVGs via fabric.loadSVGFromString(svg), the Fabric Canvas gets stuck and ultimately the browser freezes. However, I don't observe any problems when I use fabric.Image.fromURL(base64Svg). However, I can't utilize base64 converted images since the canvas.toSVG() function returns an image, which I can't use for image conversion. (In my backend, I use an SVG to JPEG converter.)
Is there a way to resolve this problem? Your assistance is much appreciated.
I am using javascript to read and manipulate pixel data in an image loaded onto a canvas. The problem is that whenever I call the .getImageData() function, I get a security error in my browser relating to having a tainted canvas. Setting the crossOrigin to "anonymous" and "use-credentials" dont work. Neither does using canvas.toDataURL. I have tried converting my image to bit64, and it didnt seem to work either (maybe I implemented it wrong). Is there any alternative to using canvas to read and manipulate pixel data in an image?
Need to generate .png images that are about ~20k in size using HTML5 canvas. Unfortunately, when creating .pngs using the toDataURL() method, you cannot specify quality like you can with jpegs.
Any ideas for a workaround? toDataURL seems to be the only way to generate images from Canvas and canvas seems to be the best tool for image processing without server interaction. Appreciate any suggestions.
There IS a way to have compression for PNG images using lossless zlib deflate process http://www.w3.org/TR/PNG-Compression.html . There is a library (https://github.com/ShyykoSerhiy/canvas-png-compression) that provides shim for HTMLCanvasElement.toDataURL() when image type is 'image/png' and enables ability to provide 'quality' as second parameter to HTMLCanvasElement.toDataURL() for png.
NOTE that it provides better results(smaller size) only in Chrome. Firefox sometimes has better compression than canvas-png-compression(as for 0.0.3 version).
You can do something by scaling it down and then scaling it up again.
Scale down by drawing it on a smaller canvas, then get the data url.
Create an image object set the data url as its source.
Draw on the original canvas with this img object (obviously inside the onload event callback)
Find the size ratio of the canvases to give you optimum result by experimenting a bit.
I have dynamically loaded a JPEG image into a 2D html canvas and I would like to access the raw YCbCr pixel values.
From what I understand, JPEG encodes the pixel data in YCbCr, but chrome appears convert it to RGB when accessing it with getImageData().
I have tried using the RGB to YCbCr conversion calculations but it appears to be a lossy conversion as they don't map perfectly 1-to-1.
Is it possible to access the raw YCbCr pixel values in JavaScript?
Yes and no.
When the browser loads an image with the native methods (ie. Image element) the YCbCr (in case of JPEGs) are automatically converted to RGB space by the browser and ICC and gamma correction is applied by browsers which support that.
This mean that when the image is loaded and ready for use, it is already in RGB space (which is correct as the monitor is RGB). The canvas does not have a part in this process and will always contain pixels as RGBA. All browsers supporting canvas will therefor return the data as RGBA when using getImageData().
The only way to access raw YCbCr is to do a low-level parse of the raw file yourselves. You can do this in any language that can iterate bytes including JavaScript. For JS I would recommend using typed arrays and DataViews to parse over the data but be warned: this is tedious and prone to errors (as it is a whole project on its own) but fully possible to do if you absolutely need the raw data.
Another way is to convert RGB back to YCbCr but chroma and the aforementioned color- and gamma-corrections will probably affect the result not making it identical to the original raw data (which in any ways is in compressed form). You can also export canvas as JPEG using the toDataURL() method on the canvas element.
I know this is a very old question, but wanted to provide the update that Chrome now rasterizes some JPEG and WebP images directly from YUV planes. You must have GPU rasterization enabled (and Metal disabled) and might sometimes need to enable the feature from chrome://flags
You can run a trace, decode an image, and include the blink category and see if any events pop up for YUV decoding. If so, then you can experiment with trying to directly access the YUV planes from JavaScript, although I'm admittedly doubtful that will work out of the box (for plumbing/security reasons).