0

With the canvas tag, how do I change the color of specific pixels at a specific locations, without using things like ctx.lineTo or ctx.fillRect?

Example:

My canvas tag is 500 pixels by 600 pixels, how do I turn the pixel at location 100 on the x-axis and 200 on the y-axis to blue?

A Bogus
  • 3,852
  • 11
  • 39
  • 58
  • possible duplicate of [What's the best way to set a single pixel in an HTML5 canvas?](http://stackoverflow.com/questions/4899799/whats-the-best-way-to-set-a-single-pixel-in-an-html5-canvas) – luiges90 Feb 17 '14 at 14:58

1 Answers1

0

Here's a function to get/replace the color at a specified pixel:

// test
setPixel(100,200,0,0,255);

function setPixel(x, y, red, green, blue) {
    var pxData = ctx.getImageData(x,y,1,1);
    pxData.data[0]=red;
    pxData.data[1]=green;
    pxData.data[2]=blue;
    pxData.data[3]=255;
    ctx.putImageData(pxData,x,y);
}

If you're doing many pixels then you can pull the getImageData to a variable outside setPixel for better performance:

var pxData = ctx.getImageData(x,y,1,1);

// test
for(var x=100;x<125;x++){
    setPixel(x,200,0,0,255);
}

function setPixel(x, y, red, green, blue) {
    pxData.data[0]=red;
    pxData.data[1]=green;
    pxData.data[2]=blue;
    pxData.data[3]=255;
    ctx.putImageData(pxData,x,y);
}
markE
  • 102,905
  • 11
  • 164
  • 176
  • In the second example I would move the `ctx.putImageData` out of the loop. – Philipp Feb 17 '14 at 15:56
  • Also worth mentioning: While most canvas operations are usually hardware-accelerated, anything you do between `getImageData` and `putImageData` is not, which makes the performance of direct pixel-manipulations quite slow in comparison to most other operations. When you want lots of real-time pixel level manipulation, you could look into WebGL and use pixel shaders executed on the GPU. – Philipp Feb 17 '14 at 15:58
  • @Philipp, the looping test example breaks if you take `ctx.putImageData` out of the loop because pxData is just 1x1. ;) – markE Feb 17 '14 at 16:15
  • ah, I see what you did there. But in this case you should use [`context.createImageData`](http://www.w3.org/TR/2010/WD-2dcontext-20101019/#dom-context-2d-createimagedata). – Philipp Feb 17 '14 at 16:43
  • I prefer getImageData in the first solution. That way if I see the pixel is already blue I don't need to do the putImageData. In the loop both will work. – markE Feb 17 '14 at 17:05
  • I moved `var pxData = ctx.getImageData(x,y,1,1);` to be inside setPixel. – A Bogus Feb 17 '14 at 21:49