Javascript: resize an image using canvas

As the continuation of my previous posts on Preview image before uploading and Sending upload image contents to the server before form submission, I want to add one more feature. When I prepare the form on which a user is uploading an image, I have to assume that the image selected by a user is large. Sometimes I don’t need to upload it in full size. In such a case, I can trim and resize it using canvas.

Prerequisites

I assume that the image is already loaded to the “img” element on the page. This can be simply an image loaded from the server, but this can be also the preview image from the form, as described in the Preview image before uploading.

The process of resizing and trimming source images consists of three steps: canvas preparation, image copying, pulling data URL.

Canvas preparation

The canvas doesn’t need to be visible anywhere on the site. We can create it entirely in Javascript and we don’t have to place it on the page. Typically I’m preparing the canvas of the size of my desired image. This way I will pull the resulting image directly from my canvas element.

let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
canvas.width = 500;
canvas.height = 200;

Copy image to canvas

The copy operation defines how the image will be placed on the canvas. The “drawImage” function we will use comes with required and optional parameters:

void ctx.drawImage(image, dx, dy);
void ctx.drawImage(image, dx, dy, dWidth, dHeight);
void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

The first one is the simplest – “image” is an image element to copy to the canvas, while “dx” and “dy” define the upper left corner of the image relative to the canvas. It can be used like this:

let myImage = document.getElementById('myImageID');
ctx.drawImage(myImage, 0, 0);

In this case, my image will be placed in the upper left corner of the canvas and trimmed by the canvas’s size. If the image is smaller, the resulting canvas will contain empty space on the rest of the area. Note that you can use “dx” and “dy” that are outside the canvas area if you want to “move” the image out. If you want to trim the upper 10 pixels, you can set dy to -10.

The second one is more powerful since you can define destination image width and height. This way you can stretch or shrink the image.

The third one is the most powerful since you can also crop the source image right away. The “sx” and “sy” are the coordinates of the upper left corner of the source image you want to start the copying from, while “sWidth” and “sHeight” are defining the width and height of the copied area. In such a case, the “dx”, “dy”, “dWidth” and “dHeight” are defining placement of the part of the image copied from the source.

Pulling an image from the canvas

Now the canvas contains our desired image. The easiest way to use it is to copy the data URL and send it along using Ajax or regular form. Here is how:

let myCroppedImage = canvas.toDataURL();

Simple, isn’t it? Of course, there are also parameters you can use. By default, the resulting image is PNG type encoded in Base64 (this is what Data URL is). You can switch to JPG or WEBP and you can also define the quality of the resulting image. In my case, the default is good enough 🙂