Canvas is one of the most powerful technologies we can employ in the web field. The canvas is nothing more than a blank slate that allows the creation of graphics, which are composed of simple figures—the usual primitives: lines, circles/spheres, and squares/rectangles. As we will see later in this post, we will delve deeper into the use of Canvas and provide tutorials to show possible uses for it.
Once it is clear what the canvas is, the next thing we need to know is its compatibility; many browsers today have support for working with the Canvas API. Major browsers like Google Chrome and Firefox, and even Microsoft browsers, support this powerful technology that allows us to draw both simple and complex graphics, as well as create compositions of images or photographs as we saw in other posts:
And also real-time video rendering; so Canvas is basically that: a canvas where we can perform drawings.
It all starts through the <canvas> tag, which enables an area or rather a canvas where it is possible to draw, write, or even render images through scripts created with JavaScript, which is the programming language selected to work with this technology:
<canvas id="myCanvas" width="500" height="500" ><p>Your browser does not support canvas :(</p></canvas>With canvas, it is possible to create all kinds of simple or complex graphics from basic primitives such as circles, ovals, rectangles, lines, and polygons. Furthermore, they are easily animatable with the requestAnimationFrame method, and the canvas is even extendable with keyboard and mouse events, among many other features not explained in this post that would otherwise (with CSS) be practically impossible (or very difficult) to achieve, as we saw before.
Browser support for canvas
Modern browsers have had native support for the canvas tag for quite some time; however, it is recommended to verify support. Like many other tags, we can verify support from the tag itself; that is, anything located between the opening and closing canvas tags will be interpreted by browsers that do not support the tag:
<canvas> Your browser does not support Canvas </canvas>At the JavaScript level, we can perform the following validation to check if the Canvas API is supported in browsers:
function isCanvasSupported(){
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
}This leads us to the fact that the canvas must have three attributes, although one of them can also be defined by CSS; the first is the ID, which is how we access it, and the others are the width and height defined by width and height respectively.
Some advantages of using canvas in our applications
- Animatable. Every object we draw on the canvas can be animated.
- Interactive. Canvas is 100% interactive and responds to all keyboard and mouse actions.
- Flexible. We can draw anything on the Canvas: images, lines, geometric figures, polygons, etc., and animate each of those objects.
- Browser support. Most modern browsers have supported canvas for a long time.
- Canvas is a standard. Unlike other technologies such as the dying Flash and Silverlight, Canvas is part of HTML5, and any self-respecting browser must support it.
<canvas> tag.Examples and Tutorials on Canvas: How does the canvas tag work?
Finally, let's get to the interesting part of all this canvas stuff and start making our first example.
With three simple steps, we can start working with this tag:
1. Referencing the canvas from the HTML DOM with our JavaScript
The first step is to get a reference to the canvas we want to work with; in this case, the <canvas> tag has the identifier myCanvas:
var myCanvas = document.getElementById("myCanvas") 2. Obtaining the canvas context via JavaScript
To perform any operation with the canvas—meaning drawing graphics and/or images—we must obtain the context of the canvas element and access the API immediately:
Accessing the canvas context provides all the methods and properties needed to draw on it.
var ctx=c.getContext("2d"); 3. Drawing primitives
Now we can start drawing on our canvas; let's look at a series of examples that illustrate the use of canvas.
3.1 Drawing a line with canvas
The simplest example or experiment we can do consists of drawing a simple line; the "Hello World" of the Canvas world. For this, we need the following methods:
moveTo(x,y)starting point of the line.lineTo(x,y)ending point of the line.stroke()draws the line.
3.2 Drawing a circle with canvas
To draw a circle on the canvas, the following methods must be used:
- A Path is a set of drawings we perform inside a canvas; for that, we must use the
beginPath()method. We finish a Path when we output its content with theclosePath()method; nothing in the path will be drawn until the context is instructed to draw the trace withstroke(). arc(x,y,r,start,end)draws a circle on the canvas.- 'x' and 'y' indicate the center of the circle.
- 'r' radius of the circle.
- 'start' and 'end' starting and ending angles respectively.
lineTo(x,y)ending point of the line.stroke()draws the line.
3.3 Drawing text with canvas
There are two methods to draw formatted text within the canvas.
fontallows defining the text font.fillText(text,x,y)the text to draw on the canvas and its position within the canvas.strokeText(text,x,y)allows drawing text without fill on the canvas given the "x" and "y" positions.stroke()draws the line.
3.4 Drawing an image with canvas
You might wonder what the purpose of drawing an image on a canvas is, besides being able to mix it with other primitives and/or images. In addition to this, we can alter each of the pixels that make up the image and apply Digital Image Processing; this among other experiments already pointed out in other related tutorials.
Drawing a Line in a Loop with HTML5 Canvas

In this article, we will see how to draw a line in a Loop or cycle in HTML5; specifically, with the Canvas API. Although the Canvas API already offers primitives to draw a line (lineTo()), in this exercise we will paint a line using squares of variable sizes, which will be the "pixels" that make up our line. To draw a square, we will use the following function:
ctx.fillRect(X,Y,Width,Height);- X: The X coordinate of the upper-left corner of the rectangle.
- Y: The Y coordinate of the upper-left corner of the rectangle.
- Width: Width of the rectangle in pixels.
- Height: Height of the rectangle in pixels.
Drawing the line with the Canvas API
We define the size of the Canvas in pixels; the Canvas will be a square:
var tamCanvas = 360;The next step is to define how many "pixels" the line will consist of and their size:
var numCuadrados = 10;var tam = 100;Now we need to define the spacing between the "pixels", which will decrease as we increase the number of rectangles:
var espaciado = (tamCanvas-tam)/(numCuadrados-1);Now we perform a loop where we will draw the "pixels" that will form the line:
for(var i=0; i <numCuadrados; i++){
ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
ctx.fillRect(i*espaciado, i*espaciado, tam, tam);
}Interactive example
If you have doubts about how the previous parameters work, in this example you can vary the value of each parameter:

Image cropping (crop) with HTML5, Canvas
Being able to cut images, an operation also known as cropping, can be very useful in certain cases. Subdividing images into pieces is a very common operation today in any environment, and there may be many cases where you want a web application to apply the crop to an image and then be able to download it.
In this article, we will see how to crop images and save them on our computer or mobile device using HTML5 and jQuery; specifically, we will use the following technologies:
- Canvas and its JavaScript API to crop, load, and save the image.
- JavaScript: for handling events and calling functions to provide support.
How the image cropping experiment works
The operation is simple and can be explained as follows:
- The user performs a first click on the canvas; we capture the coordinates of the click.
- The user drags the mouse (without holding the click) until reaching the point of interest; as they move over the Canvas, a hover will be shown representing the crop area of interest located from the first click.
- The user performs a second click on the canvas; we capture the coordinates of the click.
- The image is generated from the canvas.
It follows the same procedure as image processors like GIMP or Photoshop.
The drawImage() method
The drawImage() method allows drawing an image, Canvas, or video inside a Canvas; it receives as mandatory parameters:
- Element: Image, video, or canvas to use.
- X: X coordinate indicating from which point the image is drawn in the canvas.
- Y: Y coordinate indicating from which point the image is drawn in the canvas.
The function mode varies according to the number of parameters we pass to it:
drawImage(img,x,y): The image is painted on the Canvas starting from coordinates X and Y.drawImage(img,x,y,width,height): The image is copied starting from points "x" and "y" with the width and height defined by width and height.drawImage(img,sx,sy,swidth,sheight,x,y,width,height): The image is cropped starting from points sx and sy with the width and height defined by swidth and sheight, then the image is copied to the Canvas starting from points "x" and "y" with the width and height defined by width and height.
1. Global variables and initialization
In this part, we will define the variables used for creating this example; I will skip their explanation as their functions are explained in the comments of the code shown below:
//*** Global variables
// Canvas and its context
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Image element where the cropped image will be placed
var canvasImg = document.getElementById('canvasImg');
// Path to the source image
var imgSource = "image.jpg";
// X and Y coordinates of the first click on the canvas
var iniX;
var iniY;
// X and Y coordinates of the second click on the canvas
var endX;
var endY;
// Calculated width and height based on the first and second clicks
var imgW;
var imgH;
// Hover element that overlays the canvas based on user selection
var hover = document.getElementById('hoverCut');
// Initialize components for image cropping
function init() {
// User's first click indicating the start of the crop area
iniX = -1;
iniY = -1;
// User's second click indicating the end of the crop area
endX = -1;
endY = -1;
// Width and height of the cropped image
imgW = -1;
imgH = -1;
// Boolean to indicate if the hover should be displayed
hoverBol = false;
// Reset hover div dimensions
hover.style.width = "0";
hover.style.height = "0";
}The init() method allows initializing variables and disabling the hover (setting its width and height to zero); a call to this method will be made for each crop the user performs on the Canvas.
2. Drawing an image on the Canvas
A method is now defined to allow loading a source image into a Canvas for manipulation:
// Loads the canvas content into an img tag
function loadImageToCanvas() {
// Create an Image object and assign it a source image
newImg = new Image();
newImg.src = imgSource;
// Paint the image onto the canvas only after it has finished loading
newImg.onload = function() {
// Rescale the canvas to the size of the image
canvas.width = newImg.width;
canvas.height = newImg.height;
ctx.drawImage(newImg, 0, 0);
};
}- In lines 4 and 5, we create an Image object and assign it a source image.
- In lines 10, 11, and 12, after the image is loaded, the Canvas is scaled to the dimensions of the image and the image is painted on the Canvas.
3. Returning Canvas Content to an img Tag (image)
Previously, we passed image content to the Canvas; now we will do the opposite. The method will allow loading the Canvas content into an image; it will also copy the content of an image into an a tag to be able to download the cropped image (the final one generated by the user's crop operation).
// save the canvas to an image
function saveCanvasToImage() {
var dataURL = canvas.toDataURL();
canvasImg.src = dataURL;
document.getElementById("downloadImage").href = dataURL;
}4. Click Event on the Canvas
The next step is to capture two user clicks on the Canvas; these will allow calculating the rectangular area for cropping the image:
// Click event on the canvas
canvas.addEventListener('click', function(e) {
const rect = canvas.getBoundingClientRect();
// Use pageX/Y to get the absolute position in the document (includes scroll)
// Then subtract the canvas position within the document.
const auxX = e.pageX - (rect.left + window.scrollX);
const auxY = e.pageY - (rect.top + window.scrollY);
// First click
if (iniX < 0) {
// First point
iniX = auxX;
iniY = auxY;
// Position the 'hover' div using absolute document coordinates
hover.style.left = e.pageX + "px";
hover.style.top = e.pageY + "px";
} else {
// Second click (Second point)
endX = auxX;
endY = auxY;
// Dimensions of the new image
imgW = endX - iniX;
imgH = endY - iniY;
// Store the image in an img tag
const newImg = new Image();
newImg.src = imgSource;
// Once the image has finished loading
newImg.onload = function() {
// It is vital to reset the size before drawing to avoid stretching
canvas.width = imgW;
canvas.height = imgH;
// Clear the canvas (for a clean cut)
ctx.clearRect(0, 0, imgW, imgH);
// Crop the image
// ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
ctx.drawImage(newImg, iniX, iniY, imgW, imgH, 0, 0, imgW, imgH);
// Save the crop to an image
saveCanvasToImage();
// Load the image back onto the canvas
loadImageToCanvas();
// Reset selection and clicks
init();
};
}
});Analyzing the previous function...
If we look closely, the body of the function handled by the click event on the Canvas is divided into two blocks; we use the variable iniX as a flag to know if it is the first click (first block enclosed by the if()) or the second (second block enclosed by the if()):
- If it is less than zero, it means it is the user's first click on the Canvas.
- If it is different from -1, it means it is the user's second click on the Canvas.
The key point of this function is to capture the position of the user's clicks; these lines handle the X and Y axis:
const rect = canvas.getBoundingClientRect();
const auxX = e.clientX - rect.left + window.scrollX;
const auxY = e.clientY - rect.top + window.scrollY;- We capture the coordinates of the user's click on the browser window with
e.clientXande.clientY. - The
offset()method allows obtaining the X and Y coordinates relative to an element. - The
scrollLeft()andscrollTop()methods allow obtaining the scroll bar position of an element; in this case, thebody.
We also position the hover over the user's first click; since it has a position:absolute attribute, it is not necessary to use the offset() method because it has an absolute position rather than a relative one.
5. The hover over the Canvas
Now we will place a semi-transparent hover from the user's first click to wherever they move on the Canvas; for this, we repeatedly change the height and width of the hover as the user moves across the canvas; the explanation is similar to point 4:
// Draw a div over the canvas from the user's first click
// until where the user moves the mouse
canvas.addEventListener('mousemove', function(e) {
// If the user has made a first click
if (iniX >= 0) {
// Get the canvas position relative to the viewport
const rect = canvas.getBoundingClientRect();
// Current mouse position in the document
const currentX = e.pageX - (rect.left + window.scrollX);
const currentY = e.pageY - (rect.top + window.scrollY);
// Calculate absolute width and height to avoid negative values
imgW = Math.abs(currentX - iniX);
imgH = Math.abs(currentY - iniY);
// If the user drags backwards (left or up),
// we must update the origin (top/left) of the hover div
if (currentX < iniX) {
hover.style.left = e.pageX + "px";
}
if (currentY < iniY) {
hover.style.top = e.pageY + "px";
}
// Apply dimensions to the 'hover' element
hover.style.width = (imgW - 3) + "px";
hover.style.height = (imgH - 3) + "px";
}
});Final Result:
There is another way we can apply crops to images—though, of course, you cannot generate a new image from it—which is through negative margins. This simply involves specifying negative margins, although you can only crop from the edges and not in the middle of the image. The other way we have is by using the clip property we saw in this post:
The clip-path property in CSS to select regions to display in elements
Detecting keyboard events with Canvas

Now we are going to look at a small experiment where we interact with the Canvas through keyboard events, specifically using the keyboard arrow keys.
Performing animations with JavaScript and Canvas that depend on external agents like the keyboard or mouse is very simple.
As you can imagine, introducing the concept of animation implies the use of the requestAnimationFrame() function, which allows performing animations with Canvas efficiently. However, you must consider compatibility with older browsers as it is part of the HTML5 API; you can get more information at: THE SECRET OF ANIMATIONS IN JAVASCRIPT.
Starting the experiment with Canvas, animations, and keyboard events (JavaScript)
The experiment consists of moving a small circle across the Canvas, leaving a slight trail in its path using the keyboard arrow keys.
Initializing the keyboard event
We will associate the event with the document, although you can also associate it with the Canvas if you prefer:
document.addEventListener('keydown', function(e) { }, false);In the 'keydown' listener, we will associate the codes of the keys we want the Canvas to interact with and update variables that are used when redrawing the circle via the requestAnimationFrame() function.
You can look up the codes associated with pressing the arrow keys or simply use an alert or console.log to check the code when pressing the keys.
Once we have the codes, we can create the following conditionals to increment/decrement a series of variables:
document.addEventListener('keydown', function (e) {
lastDownTarget = event.target;
if (e.keyCode === 37) {
x-=v;
}
if (e.keyCode === 38) {
y-=v;
}
if (e.keyCode === 39) {
x+=v;
}
if (e.keyCode === 40) {
y+=v;
}
}, false);- The variables
xandyare global and represent the circle's position at a given moment; by default, both are initialized to zero. - The variable
vis a global constant that expresses the movement speed of the circle.
x represents the circle's position on the X axis, and y represents the circle's position on the Y axis.
Painting on the Canvas
So far, we have seen how to update a couple of variables via keyboard events. These variables will be used to draw the circle at a specific position. Now let's see how to draw the circle using those positions:
function draw() {
$.fillStyle = 'hsla(' + (x*y)/100 + ',100%, 50%, 1)';
$.beginPath();
$.arc(x, y, 8, 0, dosPi);
$.fill();
}Very simple: we simply query the global variables x and y that we update in another function.
In other words, as we update the variables via keyboard events, they must also be updated when repainting the Canvas through the requestAnimationFrame() function:
function go() {
$.fillStyle = 'hsla(0,0%,0%,.08)';
$.fillRect(0, 0, w, h);
if (x <= 0)
x = 0;
if (y <= 0)
y = 0;
if (x >= w)
x = w;
if (y >= h)
y = h;
draw();
window.requestAnimationFrame(go);
}The complete code for the Canvas experiment:
var c = document.getElementById('canv');
var w = c.width = window.innerWidth;
var h = c.height = window.innerHeight;
var $ = c.getContext('2d');
var x = w/2;
var y = h/2;
var dosPi = Math.PI * 2;
var v = 5;
window.addEventListener('resize', function () {
c.width = window.innerWidth;
c.height = window.innerHeight;
}, false);
function draw() {
$.fillStyle = 'hsla(' + (x*y)/100 + ',100%, 50%, 1)';
$.beginPath();
$.arc(x, y, 8, 0, dosPi);
$.fill();
}
function go() {
$.fillStyle = 'hsla(0,0%,0%,.08)';
$.fillRect(0, 0, w, h);
if (x <= 0)
x = 0;
if (y <= 0)
y = 0;
if (x >= w)
x = w;
if (y >= h)
y = h;
draw();
window.requestAnimationFrame(go);
}
go();
document.addEventListener('keydown', function (e) {
lastDownTarget = event.target;
if (e.keyCode === 37) {
x-=v;
}
if (e.keyCode === 38) {
y-=v;
}
if (e.keyCode === 39) {
x+=v;
}
if (e.keyCode === 40) {
y+=v;
}
}, false);To keep this post from being extremely long, we will leave it here. In later posts, we will see how to interact more with the Canvas using keyboard events.
You can try the experiment at the following link:
Scaling and cropping images with Canvas
Continuing with the canvas tutorials, today we will see how to apply crops to certain sections of images, which is known as a crop operation on the images we want to set. As you already know, with canvas it is possible to scale and even crop images drawn on the canvas, all with just one function called drawImage(). As we will see in this article, its mode or use varies depending on the number of parameters present; let's see:
Parameters of the drawImage() function for drawing on the canvas
These are the parameters of the drawImage() method:
| Parameter | Description |
|---|---|
| Element: | Image, video, or canvas to use; in our case, it will be the canvas. |
| sx: | Optional. The x-coordinate where the cropping starts within the element. |
| sy: | Optional. The y-coordinate where the cropping starts within the element. |
| swidth: | Optional. The width of the cropping area. |
| sheight: | Optional. The height of the cropping area. |
| x: | The x-coordinate where painting starts on the canvas. |
| y: | The y-coordinate where painting starts on the canvas. |
| width: | Optional. The width to use; it allows scaling the image horizontally. |
| height: | Optional. The height to use; it allows scaling the image vertically. |
Drawing an image to the Canvas
The first thing we must do once we have the image we want to use is to specify it:
We simply take a source image to which we want to apply cropping using JavaScript:
<img src="/public/images/example/landscape/landscape.jpg" alt="landscape" title="landscape" id="landscape">In our experiment, it looks something like this:

And then we proceed to paint the previous image on the Canvas:
var img = document.getElementById('landscape');
drawImage(img, x, y);The image (img) is copied to the Canvas starting from the points defined by x and y; if you want to copy the complete image, the x and y coordinates must be zero.
In the following example, we can see that as x and y increase, the displayed area of the photograph becomes smaller:
Scaling an image
drawImage(image, x, y, width, height);The image (img) is copied to the Canvas starting from the points defined by x and y with the width and height defined by width and height.
In the following example, it is easy to see that as the height of the canvas increases, the image drawn on the canvas is scaled.
Cropping and Scaling an image with JavaScript
This is the most complicated mode, as you basically have to indicate the data to crop and then scale the image; note that here we will use all the parameters:
drawImage(image, sx, sy, swidth, sheight, x, y, width, height);The image (img) is copied and cut starting from points sx and sy with the width and height defined by swidth and sheight.
At this point, we would have the selection ready; in image editors like GIMP, it would conceptually be as if you had made the selection with the crop tool (only the selection).
The image is scaled; the last four parameters handle this. The sixth and seventh parameters x and y position the place where you want to draw the image on the canvas along the X and Y axes. The width and height you want the image to have are indicated with width and height. If you do not want to scale the image, the last two parameters must be equal to swidth and sheight; this way, the image will only be cropped but not scaled, as we can see in the following example.
How to separately obtain the RGB channel of an image with HTML5 and the Canvas API?
Digital image processing is a task we perform in our applications every day, from resizing images to optimize them for our applications, to cropping, and even altering color, brightness, saturation, and even obtaining the RGB channel of an image separately using Canvas, as we will see in this post.
In this article, we will see a tutorial on how to obtain the three RGB channels of an image and operate them separately. That is, we will have the RGB channels individually as seen in the promotional image of this post. Like in previous articles, we will use HTML5 and native JavaScript to achieve the goal; the body of the document does not differ much from the other exercises we did before.
Defining the HTML
The HTML is really simple, similar to what we have used in previous posts. It consists of a Canvas tag which we will use to draw the base image—that is, the image with its three channels as it is by default:
<canvas id="canvas"> <p>Your browser does not support Canvas.</p></canvas>And three images where the three RGB channels will be placed using a JavaScript that we will show in the next section of this tutorial:
<img id="r"/><img id="g"/><img id="b"/>Defining the JavaScript to obtain the RGB channels of the image

The first thing we do is define the usual global variables to get the canvas and its context. Then we get access to the images that are empty by default (the src attribute that defines the image has nothing), and we will fill them a little later with the processing we will do through the Canvas API to get the RGB channel:
//*** Global variables
var canvas = document.getElementById('canvas'); // Canvas element
var ctx = canvas.getContext('2d'); // 2D context
var imgR = document.getElementById('r'); // Image representing the Red channel
var imgG = document.getElementById('g'); // Image representing the Green channel
var imgB = document.getElementById('b'); // Image representing the Blue channel
var srcImg = "image.png"; // Source imageWe create an Image object and assign a source image, which is the one we specified previously:
img = new Image(); img.src = srcImg;Once the image is loaded, we are going to resize the Canvas to the original size of the image; we draw the image on the Canvas and place the separate RGB channels in the image by invoking the getRGB() method. These are the 3 fundamental steps that you can see in detail in the following code:
// Load the image
img.onload = function() {
// Resize the canvas to the image dimensions
canvas.width = img.width;
canvas.height = img.height;
// Draw the image onto the Canvas
ctx.drawImage(this, 0, 0);
getRGB();
};The following function allows separating the three RGB channels of an image (which in our case is the one we loaded previously) and saving them in individual variables. As we see, what we get is the imageData, which is a string or a very long text with the content of the image (similar to what happens when you open an image with Notepad or another simple text processor).
The next step we take is to dump the imageData content of each of the channels that we already have separated from the previous step into the source of each of our HTML images that we defined earlier in our HTML and referenced previously as well:
// Paints one image per channel
function getRGB() {
// Get the ImageData
var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Get the ImageData for R
var imgdR = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Get the ImageData for G
var imgdG = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Get the ImageData for B
var imgdB = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Each of these arrays will hold a single channel
var pixR = imgdR.data;
var pixG = imgdG.data;
var pixB = imgdB.data;
// This will hold all 3 channels; we will use it
// to restore the original colors to the canvas
var pix = imgd.data;
// Loop through the pixels and isolate channels
for (var i = 0, n = pixR.length; i < n; i += 4) {
// Keep the R channel
pixR[i + 1] = 0; // G
pixR[i + 2] = 0; // B
// Keep the G channel
pixG[i] = 0; // R
pixG[i + 2] = 0; // B
// Keep the B channel
pixB[i] = 0; // R
pixB[i + 1] = 0; // B
}
// Return the modified data to the Canvas: R channel
ctx.putImageData(imgdR, 0, 0);
dataURL = canvas.toDataURL();
imgR.src = dataURL;
// Return the modified data to the Canvas: G channel
ctx.putImageData(imgdG, 0, 0);
dataURL = canvas.toDataURL();
imgG.src = dataURL;
// Return the modified data to the Canvas: B channel
ctx.putImageData(imgdB, 0, 0);
dataURL = canvas.toDataURL();
imgB.src = dataURL;
// Return the original data to the Canvas: RGB channel
ctx.putImageData(imgd, 0, 0);
}Drawing an image to the Canvas
The first thing we must do once we have the image we want to use is to specify it:
We simply take a source image to which we want to apply cropping using JavaScript:
<img src="/public/images/example/landscape/landscape.jpg" alt="landscape" title="landscape" id="landscape">In our experiment, it looks something like this:

And then we proceed to paint the previous image on the Canvas:
var img = document.getElementById('landscape');drawImage(img, x, y);The image (img) is copied to the Canvas starting from the points defined by x and y; if you want to copy the complete image, the x and y coordinates must be zero.
In the following example, we can see that as x and y increase, the displayed area of the photograph becomes smaller:
Scaling an image
drawImage(image, x, y, width, height);The image (img) is copied to the Canvas starting from the points defined by x and y with the width and height defined by width and height.
In the following example, it is easy to see that as the height of the canvas increases, the image drawn on the canvas is scaled.
Cropping and Scaling an image with JavaScript
This is the most complicated mode, as you basically have to indicate the data to crop and then scale the image; note that here we will use all the parameters:
drawImage(image, sx, sy, swidth, sheight, x, y, width, height);The image (img) is copied and cut starting from points sx and sy with the width and height defined by swidth and sheight.
At this point, we would have the selection ready; in image editors like GIMP, it would conceptually be as if you had made the selection with the crop tool (only the selection).
The image is scaled; the last four parameters handle this. The sixth and seventh parameters x and y position the place where you want to draw the image on the canvas along the X and Y axes. The width and height you want the image to have are indicated with width and height. If you do not want to scale the image, the last two parameters must be equal to swidth and sheight; this way, the image will only be cropped but not scaled, as we can see in the following example.
How to separately obtain the RGB channel of an image with HTML5 and the Canvas API?
Digital image processing is a task we perform in our applications every day, from resizing images to optimize them for our applications, to cropping, and even altering color, brightness, saturation, and even obtaining the RGB channel of an image separately using Canvas, as we will see in this post.
In this article, we will see a tutorial on how to obtain the three RGB channels of an image and operate them separately. That is, we will have the RGB channels individually as seen in the promotional image of this post. Like in previous articles, we will use HTML5 and native JavaScript to achieve the goal; the body of the document does not differ much from the other exercises we did before.
Defining the HTML
The HTML is really simple, similar to what we have used in previous posts. It consists of a Canvas tag which we will use to draw the base image—that is, the image with its three channels as it is by default:
<canvas id="canvas"> <p>Your browser does not support Canvas.</p></canvas>And three images where the three RGB channels will be placed using a JavaScript that we will show in the next section of this tutorial:
<img id="r"/><img id="g"/><img id="b"/>Defining the JavaScript to obtain the RGB channels of the image

The first thing we do is define the usual global variables to get the canvas and its context. Then we get access to the images that are empty by default (the src attribute that defines the image has nothing), and we will fill them a little later with the processing we will do through the Canvas API to get the RGB channel:
//*** Global variables
// Canvas element and its context
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Image elements representing the different color channels
var imgR = document.getElementById('r'); // Red channel image
var imgG = document.getElementById('g'); // Green channel image
var imgB = document.getElementById('b'); // Blue channel image
// Source image path
var srcImg = "image.png";We create an Image object and assign a source image, which is the one we specified previously:
img = new Image(); img.src = srcImg;Once the image is loaded, we are going to resize the Canvas to the original size of the image; we draw the image on the Canvas and place the separate RGB channels in the image by invoking the getRGB() method. These are the 3 fundamental steps that you can see in detail in the following code:
// Load the image
img.onload = function() {
// Resize the canvas to the image dimensions
canvas.width = img.width;
canvas.height = img.height;
// Draw the image on the Canvas
ctx.drawImage(this, 0, 0);
// Process the color channels
getRGB();
};The following function allows separating the three RGB channels of an image (which in our case is the one we loaded previously) and saving them in individual variables. As we see, what we get is the imageData, which is a string or a very long text with the content of the image (similar to what happens when you open an image with Notepad or another simple text processor).
The next step we take is to dump the imageData content of each of the channels that we already have separated from the previous step into the source of each of our HTML images that we defined earlier in our HTML and referenced previously as well:
// Paints one image per color channel
function getRGB() {
// Get the original ImageData
var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Get separate ImageData objects for Red, Green, and Blue
var imgdR = ctx.getImageData(0, 0, canvas.width, canvas.height);
var imgdG = ctx.getImageData(0, 0, canvas.width, canvas.height);
var imgdB = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Each of these arrays will hold data for a single channel
var pixR = imgdR.data;
var pixG = imgdG.data;
var pixB = imgdB.data;
// This contains all 3 channels; we will use it
// to restore the original colors to the canvas later
var pix = imgd.data;
// Loop through pixels to isolate each channel
// We increment by 4 because the array structure is [R, G, B, A, R, G, B, A...]
for (var i = 0, n = pixR.length; i < n; i += 4) {
// Keep the Red channel (set Green and Blue to 0)
pixR[i + 1] = 0; // G
pixR[i + 2] = 0; // B
// Keep the Green channel (set Red and Blue to 0)
pixG[i] = 0; // R
pixG[i + 2] = 0; // B
// Keep the Blue channel (set Red and Green to 0)
pixB[i] = 0; // R
pixB[i + 1] = 0; // G
}
// Output the modified data back to the Canvas: Red channel
ctx.putImageData(imgdR, 0, 0);
dataURL = canvas.toDataURL();
imgR.src = dataURL;
// Output the modified data back to the Canvas: Green channel
ctx.putImageData(imgdG, 0, 0);
dataURL = canvas.toDataURL();
imgG.src = dataURL;
// Output the modified data back to the Canvas: Blue channel
ctx.putImageData(imgdB, 0, 0);
dataURL = canvas.toDataURL();
imgB.src = dataURL;
// Restore the original image data to the Canvas (RGB/Full color)
ctx.putImageData(imgd, 0, 0);
}To place each of the RGB channels in individual images, we have to process the image data we obtained in an array where only one of the channels prevails, and the other two are set to zero.
Analyzing the previous function to process the RGB channels of the images
We obtain the ImageData or data of the entire image drawn on the Canvas, which will allow us to operate on the data that composes the image at the pixel level in its RGB scale:
// Get the original ImageData (Full color)
var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Get the ImageData for the Red (R) channel
var imgdR = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Get the ImageData for the Green (G) channel
var imgdG = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Get the ImageData for the Blue (B) channel
var imgdB = ctx.getImageData(0, 0, canvas.width, canvas.height);The next step consists of obtaining all the pixels that compose the image; this information is stored in an Array:
// Each of these arrays will hold a single color channel
var pixR = imgdR.data;
var pixG = imgdG.data;
var pixB = imgdB.data;
// This will hold all 3 channels (RGB); we will use it
// to restore the original colors to the canvas
var pix = imgd.data;This section of code represents the heart of the exercise; one channel is obtained at a time, setting the rest to zero:
// We modify the channels (Note: This logic isolates colors)
for (var i = 0, n = pixR.length; i < n; i += 4) {
// Keep the Red (R) channel
pixR[i + 1] = 0; // Set Green (G) to 0
pixR[i + 2] = 0; // Set Blue (B) to 0
// Keep the Green (G) channel
pixG[i] = 0; // Set Red (R) to 0
pixG[i + 2] = 0; // Set Blue (B) to 0
// Keep the Blue (B) channel
pixB[i] = 0; // Set Red (R) to 0
pixB[i + 1] = 0; // Set Green (G) to 0
}Once we have divided the channels, the next step is to save the three RGB channels in separate images:
// Return the modified data to the Canvas: Red (R) channel
ctx.putImageData(imgdR, 0, 0);
dataURL = canvas.toDataURL();
imgR.src = dataURL;
// Return the modified data to the Canvas: Green (G) channel
ctx.putImageData(imgdG, 0, 0);
dataURL = canvas.toDataURL();
imgG.src = dataURL;
// Return the modified data to the Canvas: Blue (B) channel
ctx.putImageData(imgdB, 0, 0);
dataURL = canvas.toDataURL();
imgB.src = dataURL;
// Restore the original data to the Canvas: RGB channel
ctx.putImageData(imgd, 0, 0);Final Result
Finally, you can see the result of our experiment in the following section and download the source code:
As we can see, with HTML we can do practically everything: games, text processors, image processors where the imagination is the limit.
How to obtain black and white or grayscale images with only HTML5?

HTML5 opens the door to countless possibilities for customizing or creating specific software for our web applications of all kinds, as we have seen in many posts where we work with different HTML APIs, elements, and components in general, JavaScript, and of course CSS. Among these features we have been talking about is digital image processing, which as we have seen in subsequent installments is truly possible with HTML5 and Canvas.
Specifically, we use the Canvas API to perform these exercises. In this new installment, we will see how to obtain images in Grayscale or Black and White with HTML5.
Defining the HTML for grayscale processing
As we already explained in the introduction to Canvas, the Canvas tag allows us to use the entire Canvas API that JavaScript provides, and specifically for this tutorial, to access an image at the pixel level for its processing, which is what we are going to do next:
<canvas id="canvas"> <p>Your browser does not support Canvas.</p></canvas>We also need to have defined a source image with the possibility of downloading it, which is the one we are going to reference in our canvas to subsequently draw on it.
<img id="resul"/>This is all the HTML code we will use in our experiment so that we can draw a black and white image on our Canvas.
The JavaScript to reference the Canvas
Now we enter the most interesting part of this tutorial; we are going to define some global variables as seen below:
var canvas = document.getElementById('canvas');
canvas.getContext('2d');
document.getElementById('resul');
srcImg = "image.png";These will allow us:
- Access to the Canvas.
- Access to the Canvas context; it will allow us to draw or access the Canvas content as such.
- Access to the final image; where we will place the image in Grayscale or Black and White.
- The path to the source image, which we will use to obtain a Grayscale or Black and White image from it.
We create an object of type Image and assign the source image; this image will be our final image; that is, the image in Grayscale or Black and White.
img = new Image();
img.src = srcImg;We load the image and take the opportunity to resize the Canvas to its size; after that, we invoke the function that will be responsible for converting the image to Grayscale or Black and White:
// Load the source image
img.onload = function() {
// Resize the canvas to the image dimensions
canvas.width = img.width;
canvas.height = img.height;
// Draw the image onto the Canvas
// 'this' refers to the loaded image object
ctx.drawImage(this, 0, 0);
// Process the image to convert it to grayscale
getGrayScale();
};We will skip the detailed explanation of the function; if we look closely, part of the body has been used in several previous articles.
The point of interest here is the JavaScript that allows us to have the image in Grayscale or Black and White.
After we get the ImageData or data that composes the image:
var imgData = img.data;We iterate through the ImageData in a for loop; in each iteration of the for loop, we can access the ImageData at the pixel level and thus decompose the pixel into the RGB channel (how the pixel is formed) which is what we are interested in operating on.
Now we can get an average with the values of each RGB channel separately:
gray = parseInt((imgData[i] + imgData[i + 1] + imgData[i + 2]) / 3);We substitute the original RGB channel value to obtain the desired effect: an image in Grayscale or Black and White.
imgData[i] = gray;imgData[i + 1] = gray;imgData[i + 2] = gray;We would have a similar effect if we equalized all the R, G, and B channels with each other; that is:
imgData[i + 1] = imgData[i];imgData[i + 2] = imgData[i];Or
imgData[i] = imgData[i];imgData[i + 2] = imgData[i];Or
imgData[i] = imgData[i + 2];imgData[i + 1] = imgData[i + 2];But a better result is obtained by applying an average between the channels.
Final result for grayscale
Black and white or grayscale images with only CSS
Remember that we can convert images to grayscale or black and white using a simple CSS selector, as we saw in a previous entry on CSS filters; specifically the filter:
img { filter: grayscale(100%);}
How to change the contrast of an image with HTML5?
In this article, we will see how to increase or decrease the contrast of an image with HTML5. We will also talk a bit about the process for increasing the brightness of an image, which is a similar case.
These are some of the methods, technologies, and concepts that will be used to carry out the development of this exercise:
- Canvas: To use it as a canvas and draw an image.
getImageData(): Allows obtaining data about the image drawn on the Canvas (ImageData):ImageData.width: Width in pixels of theImageData.ImageData.height: Height in pixels of theImageData.ImageData.resolution: The pixel density that the image possesses.ImageData.data: A one-dimensional Array containing the data in RGBA (in that order), with integers between 0-255; it represents the colors that compose the image drawn on the Canvas—in other words, the pixel values that compose the image drawn on the Canvas.- img.onload: Event that manifests once the image has been loaded.
The contrast formula
It is beyond the scope of this article to define contrast in its full extent; however, we can define contrast as a variation of intensities that allows increasing the luminosity between the dark and light areas of an image, enabling better focus and clarity of the image. The formula used at the pixel level will be as follows:
newValue = ( previousValue - 128) * tan(angle) + 128Where:
- previousValue: Is the original value of a pixel in the image.
- angle: We calculate the angle as: Math.tan(val * Math.PI / 180.0);
- val: The value of the range field handled by the user.
Defining the HTML
First, we will need a Canvas, which we will use as a lienzo to paint an image and be able to manipulate it at the pixel level:
<canvas id="canvas"><p>Your browser does not support Canvas.</p></canvas>A range input (type="range") to be able to increase and decrease the contrast easily:
<input type="range" id="contrast" min="-90" max="90" step="5" value="0">Defining the JavaScript
Global variables:
// Create a new image object
img = new Image();
img.src = srcImg; // Source image path
img.onload = function() {
// Resize the canvas to the image dimensions
canvas.width = img.width;
canvas.height = img.height;
// Draw the image onto the Canvas
// 'this' refers to the loaded image
ctx.drawImage(this, 0, 0);
};First, it is necessary to create an image object to which a source image is set, which will be used to paint it on the Canvas with the drawImage() method:
// new imageimg = new Image();img.src = srcImg;img.onload = function() {// we rescale the canvas to the image dimensionscanvas.width = img.width;canvas.height = img.height;// we draw the image on the Canvasctx.drawImage(this, 0, 0);};The following function allows increasing the contrast of the image painted on the Canvas:
// Increases the image contrast
function AddContrast(val) {
// Calculate the contrast factor by converting degrees to radians using Math.tan
var contrast = Math.tan(val * Math.PI / 180.0);
// Resize the canvas to match the image dimensions
canvas.width = img.width;
canvas.height = img.height;
// Draw the source image onto the Canvas
ctx.drawImage(img, 0, 0);
// Get the ImageData (pixel array) from the canvas
var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);
var pix = imgd.data;
// Iterate through the pixels to modify contrast
for (var i = 0, n = pix.length; i < n; i += 4) {
// Adjust the Red, Green, and Blue channels of each pixel.
// The formula centers the adjustment around the midpoint (128).
pix[i] = rangeColor(128 + (pix[i] - 128) * contrast); // Red
pix[i + 1] = rangeColor(128 + (pix[i + 1] - 128) * contrast); // Green
pix[i + 2] = rangeColor(128 + (pix[i + 2] - 128) * contrast); // Blue
}
// Put the modified pixel data back onto the Canvas
ctx.putImageData(imgd, 0, 0);
}Analyzing the previous function...
We create an Image object and assign a source image.
img = new Image();
img.src = srcImg;We get the imageData of the Canvas and operate at the pixel level with ImageData.data:
// we get the ImageData
var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);
var pix = imgd.data;Finally, we alter the pixel values by adding contrast to the image pixels in their RGB notation:
for (var i = 0, n = pix.length; i < n; i += 4) { // increment the red, green, and blue values of each pixel pix[i] = rangeColor(128 + (pix[i] - 128) * contrast); pix[i + 1] = rangeColor(128 + (pix[i + 1] - 128) * contrast); pix[i + 2] = rangeColor(128 + (pix[i + 2] - 128) * contrast); }To ensure the color does not go outside the 0-255 range, we use the following function:
// validates that the color is in a valid range
function rangeColor(pix) {
if (pix < 0) pix = 0;
if (pix > 255) pix = 255;
return pix;
}Brightness
As for brightness, it consists of adding a constant (K) that is in the 0-255 range. So by just modifying this section of code:
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i] = rangeColor(128 + (pix[i] - 128) * contrast);
pix[i + 1] = rangeColor(128 + (pix[i + 1] - 128) * contrast);
pix[i + 2] = rangeColor(128 + (pix[i + 2] - 128) * contrast);
}To this other one:
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i] = rangeColor(pix[i] + K);
pix[i + 1] = rangeColor(pix[i + 1] + K);
pix[i + 2] = rangeColor(pix[i + 2] + K);
}You will easily be able to change the brightness of an image with only HTML5. The constant K can be obtained from a range input field, as in the case of contrast:
<input type="range" id="brightness" min="0" max="255" step="1" value="0">Final Result
Experiments and more examples
I show you a list of several experiments and examples that you can follow once you finish this guide:
- Drawing random points with Canvas
- Accessing the camera and microphone of a device with JavaScript
- How to create circle rings in JavaScript and Canvas
- Creating particles with JavaScript and Canvas
- How to create a luminous point with JavaScript and Canvas?
- How to create a wave effect with Canvas and JavaScript?
- The secret of animations in JavaScript (requestAnimationFrame())
I agree to receive announcements of interest about this Blog.
The canvas element allows us to specify an area of the page where we can draw and create all kinds of simple or complex graphics from basic primitives such as circles, ovals, rectangles, lines, polygons, text, etc. We will see examples of how to crop images, loops to draw lines, keyboard events, and how to obtain the RGB channel.