Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 799
Alex Lorimer Avatar asked Jan 30 '26 11:01

Alex Lorimer


1 Answers

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.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!