6

I have put an image in canvas and I want to get the RGB value of the pixels of that image when the user moves the mouse over the image. Here is the code which I have written:

<canvas id="myCanvas" width="200" height="200" style="border: red;border-style: dotted">
Your browser does not support the canvas element.
</canvas>
<script>
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");

var destX = 0;
var destY = 0;

var imageObj = new Image();
imageObj.onload = function()
{
context.drawImage(imageObj, destX, destY);
};
imageObj.src = "zain.jpg";

canvas.onclick = function(e) {
    var x = e.pageX;
    var y = e.pageY;
    var canvasColor = context.getImageData(x, y, 1,1); // rgba e [0,255]
    var pixels = canvasColor.data;
    var r = pixels[0];
    var g = pixels[1];
    var b = pixels[2];
    document.body.style.backgroundColor = "rgb("+r+','+g+','+b+")";
}
Matt Ellen
  • 11,268
  • 4
  • 68
  • 90
Zain
  • 5,391
  • 11
  • 34
  • 34
  • 1
    Two quick comments about your current code. 1. Make sure getImageData w and h are set to 1 instead (getImageData(x, y, 1, 1). 2. Set CSS like this "rgb("+r+","+g+","+b+")"; . You'll need to format the output like this to match the spec. – Juho Vepsäläinen Sep 11 '11 at 07:09
  • @bebraw i have updated the code, but still nothing happening, my code is not executing right after the getImageData() functional call. Can you please do me a favor, that you copy my code and just run it at your end. Shall be very thankful to you! – Zain Sep 11 '11 at 08:11
  • Your code appears to work here. There's one important thing to keep in mind, though! You will need to run the script on a local server. Otherwise getImageData will give you SECURITY_ERR (inspect your console for this). – Juho Vepsäläinen Sep 11 '11 at 08:20
  • i am running it on my local machine, but i dont know why my code is not executing right after the getImageData() call. :( – Zain Sep 11 '11 at 08:33
  • yes you are right it is giving the Security error right after the getImageData() function call, can you suggest me, how to handle with it? – Zain Sep 11 '11 at 08:35
  • It worked, i have handled the exceptions by try catch :) thanks alot – Zain Sep 11 '11 at 08:42

2 Answers2

9

Try something along this:

var color = document.getElementById("color");
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");

var imageObj = new Image();
imageObj.onload = function(){
    context.drawImage(imageObj, destX, destY);
};
imageObj.src = "zain.jpg";

canvas.onmousemove = function(e) {
    // not so sure about these... might need to offset them or so
    var x = e.x;
    var y = e.y;

    // set color now
    var canvasColor = context.getImageData(x, y, 1, 1).data; // rgba e [0,255]
    var r = canvasColor[0];
    var g = canvasColor[1];
    var b = canvasColor[2];

    color.style.backgroundColor = 'rgb(' + r + ',' + g + ',' + b + ')';
}

Note that the snippet expects you have a div with id "color" somewhere. It sets the pixel color there.

Juho Vepsäläinen
  • 26,573
  • 12
  • 79
  • 105
  • There's some info about the mouse coordinate problem at http://stackoverflow.com/questions/4848310/getting-mouse-position-with-javascript-within-canvas . – Juho Vepsäläinen Sep 10 '11 at 19:38
  • By using your code, the image which i was pushing in canvas is also not showing now, kindly help me out please. – Zain Sep 10 '11 at 19:51
  • i have updated the code, please have look, but still same problem i am not receiving the RGB value – Zain Sep 10 '11 at 20:04
  • 1
    getImageData() returns an ImageData object, not an array. When you access canvasColor[0...2] it doesn't contain anything. You need to access canvasColor.data[0...2] instead. – Xenethyl Sep 10 '11 at 20:06
  • Excellent point. Added that. I usually use my own Canvas wrapper instead of the pure API. ;) – Juho Vepsäläinen Sep 10 '11 at 20:08
  • Understandable. Just getting a handle to the context is annoying enough! :) – Xenethyl Sep 10 '11 at 20:14
  • @using canvasColor.data[0] still not returning me anything :( – Zain Sep 10 '11 at 20:18
  • hi, i have checked it out code line var canvasColor = context.getImageData(x, y, w, h); // rgba e [0,255] is not working, i don't know whats happening, kindly help me out – Zain Sep 10 '11 at 20:43
  • As far as I can tell, `w` and `h` are not defined in your call to `getImageData()`. All you need is one pixel, so you can hardcode values of `1` in there. Also, I'm not quite sure why you now have the comment in your post about the browser not supporting the canvas element. If your browser doesn't support the canvas element, you can't do any of this. – Xenethyl Sep 11 '11 at 01:45
  • @Xenethyl.. Browser is completely supporting my canvas, there is no issue of browser support. just the getImageData() function is not working – Zain Sep 11 '11 at 06:28
  • can anyone please suggest me the complete code in running condition. shall be very thankful – Zain Sep 11 '11 at 06:33
  • @Zain : It's important you call getImageData like this: getImageData(x, y, 1, 1). This returns the data of the given pixel. There's no need to pass w and h there in this case. – Juho Vepsäläinen Sep 11 '11 at 07:05
  • @bebraw i have updated the code, but still nothing happening, my code is not executing right after the getImageData() functional call. Can you please do me a favor, that you copy my code and just run it at your end. Shall be very thankful to you! – Zain Sep 11 '11 at 08:10
3

What you're looking for here is the getImageData() call.

So, your solution would look something like this:

function getColor(canvas, x, y) {    
    var context = canvas.getContext("2d");
    var pixel = context.getImageData(x, y, 1, 1);

    // Red = rgb[0], green = rgb[1], blue = rgb[2]
    // All colors are within range [0, 255]
    var rgb = pixel.data;

    return rgb;
}

function canvasMouseMove(e) {
    var x = e.layerX, y = e.layerY;
    var rgb = getColor(canvas, x, y);
    var rgb_string = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")";

    document.body.style.backgroundColor = rgb_string;
}

canvas.onmousemove = canvasMouseMove;

As @bebraw pointed out, you may need to handle the mouse location differently depending on the browser being used. For that, you might consider using jQuery or another JS library for simplicity.

Xenethyl
  • 3,179
  • 21
  • 31