Monday, March 14, 2022

How to Crop or Resize an Image with JavaScript

How to Crop or Resize an Image with JavaScript

It is very easy to show 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 image for your visitors or clients? We have already written 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.

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

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 you can create a new image using the Image() constructor. Here is an example:

2. Draw the Image on Canvas

We will now use an even listener to wait for the image to load and the get its original width and height. This width and height is 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 and avoid any distortions.

The drawImage() method of the canvas API will have an important role to play here. We can use it to resize as well as 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 co-ordinate of the images. Similarly, sWidth/sHeight and dWidth/dHeight represent the width and height of the images.

I have marked the sources 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 if 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

Lets say we want to resize the puppy image so that it is 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 variable newWidth determines how wide we want the image to be when resized. We then calculate newHeight by dividing the width with 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 co-ordinates and dimensions. The source image was drawn in its entirety on the new canvas. However, we can also pass arbitrary source co-ordinates 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.

Lets 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 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 re-usability of the code. Lets rewrite it in a way that allows us to call a single function to crop/resize as well as download the image. Here is the code that resizes or crops any given image to specified dimensions and then save it with 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 converted 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 some fractional value to set new dimensions with respect to the original image. 


No comments:

Post a Comment