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.