Genius
It is possible to read and write to individual pixels on a canvas.
The getImageData() function allows us to read rectangular areas from a canvas.
imageData = ctx.getImageData(x, y, width, height);
Example of reading and writting pixels on a canvas (Run Example).
<!-- Author: Derek O Reilly, Dundalk Institute of Technology, Ireland. --> <!DOCTYPE html> <html> <head> <title>Course notes example code</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> #gameCanvas { /* the canvas styling usually does not change */ outline:1px solid darkgrey; width:500px; height:500px; } </style> </head> <body> <canvas id = "gameCanvas"></canvas> <script> let img = new Image(); // note that the offscreen image must be declared OUTSIDE of the window.onload() function img.src = "images/city.png"; window.onload = function () { let canvas = document.getElementById("gameCanvas"); canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; let ctx = canvas.getContext("2d"); // draw an image on the canvas ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // get the pixels from the canvas // NOTE: getImageData() will only work if the image in drawImage is // on the same server as the webpage let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); let data = imageData.data; const RED = 0; const GREEN = 1; const BLUE = 2; const ALPHA = 3; for (let i = 0; i < data.length; i += 4) { data[i + RED] = 255 - data[i + 0]; data[i + GREEN] = 255 - data[i + 1]; data[i + BLUE] = 255 - data[i + 2]; data[i + ALPHA] = 255; } ctx.putImageData(imageData, 0, 0); }; </script> </body> </html>
let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); let data = imageData.data;
The above two lines of code above copy the selected pixels into a one-dimensional array.
const RED = 0; const GREEN = 1; const BLUE = 2; const ALPHA = 3; for (let i = 0; i < data.length; i += 4) { data[i + RED] = 255 - data[i + 0]; data[i + GREEN] = 255 - data[i + 1]; data[i + BLUE] = 255 - data[i + 2]; data[i + ALPHA] = 255; }
The for-loop above steps through each of the selected pixels. Each pixel has a red, green, blue and alpha value, each of which is in the range 0-255.
ctx.putImageData(imageData, 0, 0);
The putImageData() function allows us to write the selected pixels on the canvas.
Write code to place coloured text on a grayscale image, as shown here.
The getImageData() and putImageData() functions allow us to read/write onto any rectangular area of a canvas, as shown here.
<!-- Author: Derek O Reilly, Dundalk Institute of Technology, Ireland. --> <!doctype html> <html> <head> <title>Course notes example code</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> #gameCanvas { /* the canvas styling usually does not change */ outline:1px solid darkgrey; width:500px; height:500px; } </style> </head> <body> <canvas id = "gameCanvas"></canvas> <script> let image = new Image(); image.src = "images/city.png"; window.onload = function () { let canvas = document.getElementById("gameCanvas"); canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; let ctx = canvas.getContext("2d"); ctx.drawImage(image, 0, 0, canvas.width, canvas.height); // get the pixels from the canvas // NOTE: getImageData() will only work if the image in drawImage is // on the same server as the webpage let imageData = ctx.getImageData(canvas.width / 3, 0, canvas.width / 3, canvas.height); // x,y position and regtangle width and height let data = imageData.data; const RED = 0; const GREEN = 1; const BLUE = 2; const ALPHA = 3; // Manipulate the pixel data for (let i = 0; i < data.length; i += 4) { imageData.data[i + RED] = 255 - imageData.data[i + RED]; imageData.data[i + GREEN] = 255 - imageData.data[i + GREEN]; imageData.data[i + BLUE] = 255 - imageData.data[i + BLUE]; imageData.data[i + ALPHA] = 255; } ctx.putImageData(imageData, canvas.width / 3, 0); }; </script> </body> </html>
imageData = ctx.getImageData(canvas.width / 3, 0, canvas.width / 3, canvas.height); // x,y position and regtangle width and height
The code above shows that we only manipulate the middle one-third of the canvas.
Write code to display a greyscaled image with a coloured border, as shown here.
We can read/write any single canvas pixel by selecting a rectangle of size 1 pixel. The code below reads a single pixel.
let imageData = someOffscreenCanvas.getImageData(x, y, 1, 1);
let data = imageData.data;
if (data[ALPHA] !== 0)
{
// This pixel is not transparent
}
We can use an offscreen canvas to test the mouse pointer against the transparent and non-transparent parts of an image. This is especially useful for accurate collision detection. We shall look at this in more detail later.
Copyright Genius.