Draw image from pixel array on canvas with putImageData
Asked Answered
D

2

15

I am working on a project that can encrypt an image and redraw the decrypted image on canvas. As I am still pretty new to coding and programming, I am currently having issues redrawing the decrypted image data, which is a pixel array in the form R,G,B,A. I thought this would be possible by simply putting the data into

ctx.putImageData(imgd,0,0);

But firebug tells me that the value does not implement the interface for imagedata. I have posted the entire array here. The image is 160px wide and 120px high.

Is there any way to reformat the array so that it is drawable on the canvas?

Dose answered 9/4, 2013 at 17:9 Comment(1)
Bart - it's just the variable i assigned to the arrayDose
N
12

Assuming imgd is simply an Array containing all byte values, you still need to convert the array to ImageData.

var imgd = [27,32,26,28,33,27,30,35,29,31.....]

// first, create a new ImageData to contain our pixels
var imgData = ctx.createImageData(160, 120); // width x height
var data = imgData.data;

// copy img byte-per-byte into our ImageData
for (var i = 0, len = 160 * 120 * 4; i < len; i++) {
    data[i] = imgd[i];
}

// now we can draw our imagedata onto the canvas
ctx.putImageData(imgData, 0, 0);
Ng answered 9/4, 2013 at 17:46 Comment(2)
var imgData = new ImageData(new Uint8ClampedArray(imgd), 160, 120)?Aegeus
That's a relatively recent addition to the spec. It's an experimental API and not supported in IE.Ng
N
18

Using Uint8 you can this much quicker:

var canvas = document.createElement("canvas"),
    ctx = canvas.getContext("2d"),
    img = [27,32,26,28, ... ];

// Get a pointer to the current location in the image.
var palette = ctx.getImageData(0,0,160,120); //x,y,w,h
// Wrap your array as a Uint8ClampedArray
palette.data.set(new Uint8ClampedArray(img)); // assuming values 0..255, RGBA, pre-mult.
// Repost the data.
ctx.putImageData(palette,0,0);

No need to go byte-by-byte unless you need to modify the values first.

Nether answered 1/4, 2014 at 5:15 Comment(2)
var palette = new ImageData(new Uint8ClampedArray(img), 160, 120)?Aegeus
"palette".. hmm, that sounds like something else. I would probably call the variable "imageData" or something more helpful.Kolk
N
12

Assuming imgd is simply an Array containing all byte values, you still need to convert the array to ImageData.

var imgd = [27,32,26,28,33,27,30,35,29,31.....]

// first, create a new ImageData to contain our pixels
var imgData = ctx.createImageData(160, 120); // width x height
var data = imgData.data;

// copy img byte-per-byte into our ImageData
for (var i = 0, len = 160 * 120 * 4; i < len; i++) {
    data[i] = imgd[i];
}

// now we can draw our imagedata onto the canvas
ctx.putImageData(imgData, 0, 0);
Ng answered 9/4, 2013 at 17:46 Comment(2)
var imgData = new ImageData(new Uint8ClampedArray(imgd), 160, 120)?Aegeus
That's a relatively recent addition to the spec. It's an experimental API and not supported in IE.Ng

© 2022 - 2024 — McMap. All rights reserved.