How to Crop or Resize an Image With JavaScript

It’s very easy to show a resized or cropped version of an image on a website using CSS. However, this doesn’t change the original image data. What if you want to create an actual cropped or resized version of an image for your visitors or clients?

We’ve already published a couple of tutorials on how to create image thumbnails using PHP or apply cropping, resizing and other filters using PHP. In this tutorial, you will learn how to crop or resize an image with JavaScript.

Here’s a live demo of our image cropping code in action.

And here’s an example of the resizing code:

Things to Remember

We will need access to the original image data in order to create a new version of the image that is cropped or resized to specific dimensions. We can do that with the help of the canvas element.

The canvas HTML element has been around for a long time now, and we can use it to draw all sorts of graphics. There are hundreds of libraries out there that you can use to create graphs, vectors, and animations using the canvas API. We will use the API in this tutorial to create our cropped and resized images.

One thing that you should keep in mind is that getting access to the image data for manipulating it with a canvas requires you to either have the image on the same server or use the crossorigin attribute to indicate that the canvas has permission to access, modify, and save the image data.

1. Load the Image Data

The first thing that we need to do is load our image data. You can do that either by referencing an image that has already been loaded in the DOM or by creating a new image using the Image() constructor. Here is an example:

2. Draw the Image on the Canvas

We will now use an event listener to wait for the image to load and then get its original width and height. This width and height are used to determine the aspect ratio of the image. Having access to the aspect ratio will allow us to resize the image without stretching it in either direction, so that we can avoid any distortion.

The drawImage() method of the canvas API will have an important role to play here. We can use it to resize and crop our images by passing an appropriate number of arguments. It can accept three, five, or nine parameters and has the following syntax.

We will be using the second version for our resizing functionality and the third version to implement cropping. The first parameter is the image element that you want to draw on the canvas. The prefixes s and d signify the source and destination for our original and new image. This means that (sx, sy) and (dx, dy) represent the top-left coordinate of the images. Similarly, sWidth/sHeight and dWidth/dHeight represent the width and height of the images.

I have marked the source values on the puppy image from Pixabay that we will be cropping to give you an idea of what these parameters signify.

Cute PuppyCute PuppyCute Puppy

The top-left corner of the image is considered to be (0, 0), and the bottom-right corner corresponds to (imageWidth, imageHeight). This means that we can get the whole image by setting the values of sx, sy, sWidth, and sHeight to 0, 0, the image width, and the image height respectively.

Resizing the Image

Let’s say we want to resize the puppy image so that it’s only 500 pixels wide. We can use the following JavaScript code to resize our image. We will modify this code later to be a callable function so that the width is no longer hard-coded and the height can be set arbitrarily when users don’t want to preserve the aspect ratio.

Inside our event listener, we use the naturalWidth and naturalHeight property of our Image object to get its dimensions. We use this information to get the aspect ratio of the image. The value of the newWidth variable determines how wide we want the image to be when it’s resized. We then calculate newHeight by dividing the width by our calculated aspect ratio.

These values are also used to set the width and height of the canvas. We simply use the drawImage() method to draw our image on the canvas after that.

Cropping the Image

You might recall from our earlier discussion that calling the drawImage() method with five parameters only requires us to pass the destination coordinates and dimensions. The source image was drawn in its entirety on the new canvas. However, we can also pass arbitrary source coordinates and dimensions to the drawImage() method in order to only draw a part of the source image. Here is a very basic implementation to crop an image in JavaScript.

We will improve this code later so that the values are not hard-coded but derived from a callable function. The croppedHeight will also be automatically determined from the croppedWidth and aspect ratio when users don’t pass its value.

3. Downloading the Image

Unless the goal was to simply render the cropped or resized image on a webpage, you will probably also want to give users the ability to download an image. We can achieve this with minimal effort by using the toDataURL() method. It accepts two parameters that allow you to specify the file format and image quality.

Let’s say you have a download button on your webpage with the following HTML:

We can then use the following JavaScript to create a temporary dummy link which will allow us to download our image.

Clicking on the download button now will start the download of a file named puppy-cropped.jpg.

4. Create Reusable Cropping and Resizing Functions

A lot of values in our code are currently hard-coded. This severely limits the reusability of the code. Let’s rewrite it in a way that allows us to call a single function to crop, resize, and download the image. Here is the code that resizes or crops any given image to the specified dimensions and then saves it with a given name.

Final Thoughts

In this tutorial, we learned how to crop and resize an Image in JavaScript using the canvas API. All we need to do is draw the image over the canvas with the drawImage() method and then convert it to image data using the toDataURL() method.

Since we already have the image loaded on the canvas, you should try to implement additional functionality like letting users pass a fractional value to set new dimensions with respect to the original image.