I am doing a Ajax call to Server for a Jpeg file. I have the data returned as Array buffer. Now how can I render this Array buffer on the canvas. Now please dont suggest any answer like setting the source url to the image. I want to hold the image data on memory for some processing.
1 Answers
If you don't want to use the buffer as an image source, the only option left is to parse the raw buffer yourself. Just have in mind that this buffer contains the unprocessed (raw) file, so by parsing it means low-level byte parsing (using a DataView
).
It's doable but you need to handle all aspects of parsing JPEG files such as header, format areas, decompressing and decoding any kind of image buffers (RGB, CMYK, YUV etc.), validation and error handling.
However, this can be unpractical unless you intend to use special aspects of the JPEG file such as retrieving for example raw CMYK data.
So the only practical way, if you want to avoid using a JavaScript parser, is to convert your ArrayBuffer to Base-64 (going by a view such as Uint8Array), prepend it with a data-uri header, and then set it as src for an Image object. Better yet, just set the URL as image source directly and let the browser parse and decode the file.
There are essentially only two ways to get image data into canvas:
- using an image source which can be Image, Video, Canvas or a context.
- Writing raw pixel data using ImageData objects.
For the latter you need to get the bitmap from somewhere, usually another or the same canvas, or from an external source in form of raw uncompressed bitmap data, or a file you pass on to the browser to process, or you process using the low-level approach mentioned earlier (both cases require CORS requirements to be fulfilled).
Sorry, there are no other ways..
You can still draw the JPEG image to canvas and then extract the image data (pixels):
context.drawImage(image, x, y); // image to canvas
var imageData = context.getImageData(x, y, width, height); // get ImageData object
var uint8clampedarray = imageData.data; // get the 8-bit view
var arraybuffer = uint8clampedarray.buffer; // the raw byte buffer
-
Thank you for the reply. Ok Say I have Jpeg Data as BLOB.. So How can I draw this on the canvas? – Raj Mar 03 '15 at 09:24
-
@Raj you need to create an [ObjectURL](https://stackoverflow.com/questions/14952052/convert-blob-url-to-normal-url) for the Blob and set that as a source to an image object. But this is unneeded overhead, just set the original URL as image source directly. There are only two ways to draw to canvas, one being using an image source (image, video, canvas, context) or using a pixel buffer. The problem is that your original arraybuffer contains the raw unprocessed file so you can't use that directly without either your app parsing it, or just let the browser parse it. – Mar 03 '15 at 09:26
-
1Ya I clearly got you, Now I am creating a image object and setting its URL and finally onload of the image I just draw the image on the canvas. All the decoding is handled by the browser. Thanks for the reply. This is my code... var img = new Image(); img.onload = function () { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img,0,0); }; img.src = url; – Raj Mar 03 '15 at 09:51