0

I am trying to invert the color of an image. Now the image loads ok, but when I try to call getImageData and putImageData back onto the canvas. The canvas is simply blank. Then I printed out all imageData, it appears like that it is always 0 for some reason. I am seriously troubled by this. Please help and thx in advance!

window.onload = function() {
    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    var img = new Image();
    img.src = "hand.jpg";
    img.onload = function() {
        ctx.drawImage(img, 10, 10,50,50);
    }

    var imgData = ctx.getImageData(10,10,50,50);
    console.log(imgData.data.toString()); //return 0's 
    for (var i=0;i<imgData.data.length;i+=4)
    {
        imgData.data[i]=255-imgData.data[i];
        imgData.data[i+1]=255-imgData.data[i+1];
        imgData.data[i+2]=255-imgData.data[i+2];
        imgData.data[i+3]=255;
    }
    ctx.putImageData(imgData,100,100);
}

UniSound Waterloo
  • 531
  • 1
  • 7
  • 22

1 Answers1

3

You need to wait for the image to load

window.onload = function() {
    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    var img = new Image();
    img.src = "hand.jpg";
    //================================================================
    // this event will only get called after you have returned from this function
    img.onload = function() {
        ctx.drawImage(img, 10, 10,50,50);
    }
    //================================================================
    // The image has not loaded at this point
    // the following code will always be working on an empty canvas

    var imgData = ctx.getImageData(10,10,50,50);
    console.log(imgData.data.toString()); //return 0's 
    for (var i=0;i<imgData.data.length;i+=4)
    {
        imgData.data[i]=255-imgData.data[i];
        imgData.data[i+1]=255-imgData.data[i+1];
        imgData.data[i+2]=255-imgData.data[i+2];
        imgData.data[i+3]=255;
    }
    ctx.putImageData(imgData,100,100);

    //================================================================
    // onload will fire after this point
}

To fix

window.onload = function() {
    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    var img = new Image();
    img.src = "hand.jpg";
    img.onload = function() {
        ctx.drawImage(img, 10, 10,50,50);

        var imgData = ctx.getImageData(10,10,50,50);
        for (var i=0;i<imgData.data.length;i+=4){
            imgData.data[i]=255-imgData.data[i];
            imgData.data[i+1]=255-imgData.data[i+1];
            imgData.data[i+2]=255-imgData.data[i+2];
            imgData.data[i+3]=255;
        }
        ctx.putImageData(imgData,100,100);
    } 
}

BTW you can invert the image colours with

ctx.globalCompositeOperation = "difference";
ctx.fillStyle = "white"
ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.globalCompositeOperation = "source-over"; // restore default
Blindman67
  • 51,134
  • 11
  • 73
  • 136
  • Thank you so much! I wouldn't have expected that. Now I have another question. I copied your code and it says (The canvas has been tainted by cross-origin data.) I know this is a common problem, but all the answers on stackoverflow doesn't apply to me. I am only running this on my local – UniSound Waterloo Sep 19 '16 at 23:34
  • 1
    @UniSoundWaterloo If you are running on localhost ensure that the image is also coming from the same. You can not use the image if it is coming from the file store – Blindman67 Sep 20 '16 at 00:04
  • Man, you are awesome! – UniSound Waterloo Sep 20 '16 at 00:39