Alex Lorimer
Alex Lorimer

Reputation: 497

Generating an RGB image using javascript instead of an RGBA

I'm currently using context.createImageData(width, height) to create an RGBA image with HTML5 canvas. However I don't need to manipulate the images alpha values, so the array that I'm creating is quite a bit larger than it needs to be. Is there no way to use a similar method that creates RGB image data?

Upvotes: 3

Views: 4708

Answers (1)

user1693593
user1693593

Reputation:

You simply can't using canvas.

Canvas will always give you a RGBA buffer as per specification (the only exception it produces RGB is when you use toDataURL to produce a JPEG).

You can simply ignore the alpha channel and leave it with value 255, or create a custom Typed Array buffer with only RGB values which you manipulate and then copy over the data to canvas' pixel array.

var myBuffer = new ArrayBuffer(3 * w * h);    /// calc buffer size in bytes
var pixels = new Uint8ClampedArray(myBuffer); /// view for buffer

Uint8ClampedArray is the same type of buffer view as the canvas is using.

Then copy the values from pixels to the image data when the data is ready:

var imageData = ctx.createImageData(w, h);   /// create a canvas buffer (RGBA)
var data = imageData.data;                   /// view for the canvas buffer
var len = data.length;                       /// length of buffer
var i = 0;                                   /// cursor for RGBA buffer
var t = 0;                                   /// cursor for RGB buffer

for(; i < len; i += 4) {
    data[i]     = pixels[t];     /// copy RGB data to canvas from custom array
    data[i + 1] = pixels[t + 1];
    data[i + 2] = pixels[t + 2];
    data[i + 3] = 255;           /// remember this one with createImageBuffer

    t += 3;
}

ctx.putImageData(imageData, 0, 0); /// put data to canvas

(the two buffers needs to match in width and height of course).

If this approach is beneficial largely depends on if you do much processing of the image or not. If not then this will only use more memory and won't give much benefit in performance.

Depending on how and what you will process there is also the possibility to use a Uint32Array with your custom buffer (in addition to the Uint8ClampedArray - you can have as many views as you want on a buffer) which is useful for pixel displacement and so forth.

Upvotes: 7

Related Questions