Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript imageData returns array of 0's

I am trying to manipulate imageData but my imageData array returns all 0's after I load up the image and get its pixel data.

There are a few html elements like sliders and text boxes. Please ignore those.

There is an ImageObject data structure where I am storing all image properties like image,pixelData and so on..

i first load the image, get its pixel data and then return a callback to store ImageObject.imageData. However in the log ImageObject.data returns all 0's.

ImageObject = {};
var MainCtx;
var MainCanvas;
//get the image pixel properties

function start()
{
    //load up the main canvas and ctx 
    MainCanvas = document.getElementById("canvas");
    MainCtx = MainCanvas.getContext('2d');

    //first load up the image and then get its pixel data
    ImageObject.loadImage(function(imageData){
        ImageObject.imageData = imageData;
        ImageObject.data = ImageObject.imageData.data;

        console.log(ImageObject.data); // -> data return all 0's in the array

        for(var i = 0; i < ImageObject.data.length; i += 4) {
            var brightness = 0.34 * ImageObject.data[i] + 0.5 * ImageObject.data[i + 1] + 0.16 * ImageObject.data[i + 2];
          // red
          ImageObject.data[i] = brightness;
          // green
          ImageObject.data[i + 1] = brightness;
          // blue
          ImageObject.data[i + 2] = brightness;
      }

      ImageObject.ctx.putImageData(ImageObject.imageData,ImageObject.image.width,ImageObject.image.height);
  });
}

ImageObject.loadImage = function(callback)
{
    ImageObject.image = new Image();
    ImageObject.image.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
    ImageObject.image.addEventListener('load',function()
    {
        MainCtx.drawImage(ImageObject.image,0,0);
        callback(ImageObject.getImageData(ImageObject.image));
    });
}

ImageObject.getImageData = function(img)
{
    this.canvas = getCanvas(img.width,img.height);
    this.ctx = this.canvas.getContext('2d');
    return this.ctx.getImageData(0,0,this.canvas.width,this.canvas.height);
}

function getCanvas(w,h)
{
    var c = document.createElement('canvas');
    c.width = w;
    c.height = h;
    return c;
}

start();

I have shared the jsFiddle link below

jsFiddle

Can someone please take a look as to what am I doing wrong?

like image 421
Htlcs Avatar asked Mar 21 '15 18:03

Htlcs


3 Answers

Your issue is that you're getting your image data from a new canvas that you have created inside the getCanvas function. You need to run getImageData on the existing canvas.

Here is an update to the console.log

console.log(MainCtx.getImageData(0, 0, MainCanvas.width, MainCanvas.height));

This still will not work straight away as you are loading the image from a different origin, so make sure you host the image locally, first.

like image 144
Ryan Avatar answered Nov 05 '22 13:11

Ryan


Try to put the information inside a 32 bit unsigned integer array through its buffer.

Something like

var img = canvas.getImageData(),
data32 = new Uint32Array(img.data.buffer);

//loop through the pixels
for(var i=0; i<data32.length, i++){
var pixel = data32[i];

//get the colors
var r = (pixel) & 0xff,
g = (pixel >> 8) & 0xff,
b = (pixel >> 16) & 0xff;
a = (pixel >> 24) & 0xff;

//put the pixels back in (no change)
data32[i] = (a << 24)
| (b << 16)
| (g << 8)
| r;
}

Author: Matt Lockyer

Retrieved from: http://mattlockyer.github.io/iat455/workshop-1.html

like image 35
Kelv.Gonzales Avatar answered Nov 05 '22 13:11

Kelv.Gonzales


The quick answer is:

You try to get image data from a new(empty) canvas.

Explanation:

In your function getImageData, you set your canvas using a function called getCanvas. In this function, instead of using your actual canvas with your image drawn on it, you create a new canvas (document.createElement('canvas');)

Since, you have set your canvas as MainCanvas, you should use it in your function getImageData like this:

this.canvas = MainCanvas;

Unfortunately, I can't make it work in your jsfiddle because of Cross-Origin Resource Sharing policy.

like image 1
service-paradis Avatar answered Nov 05 '22 13:11

service-paradis