Skip to main content

How to Resize an Image in 10 Lines of Javascript

Gregory Schier Headshot Gregory Schier • 4 min read

Allowing users to upload photos directly to a website, without first resizing them, hurts the user experience for two reasons.

  1. Large photos take time to upload ⏱
  2. Large photos cost the user money in bandwidth 💸

Photos should be resized on the client before uploading, especially now that smartphones are available that can capture 100MP photos. Luckily there's an easy way to do it using the <canvas> element and a few lines of JavaScript.

See the Pen Resizing images with vanilla JS and <canvas> by Gregory Schier (@gschier) on CodePen.

Resize Images Using <canvas>#

The <canvas> element is typically used for games and other visual apps to draw things that cannot be represented by standard HTML elements. For our purposes, we'll use an invisible canvas element as an image manipulation tool.

This tutorial focuses on resizing, specifically, but similar techniques can be used to crop or apply filters to images.

We can do the following steps to resize an image.

  1. Create a canvas of the same aspect ratio, but smaller (400x300px)
  2. Draw the image to the canvas, taking up the full width and height
  3. Export the contents of the canvas to an image
  4. Use the exported image as needed

All of this takes less than 10 lines of code!

JavaScript Snippet
// Create an image element
const img = document.createElement('img');

// Or, reference existing image on page
// const img = document.querySelector('#my-image');

img.addEventListener('load', () => {
  // Initialize the canvas and it's size
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");

  // Set width and height
  canvas.width = 200;
  canvas.height = 150;

  // Draw image and export to a data-uri
  ctx.drawImage(imgEl, 0, 0, canvas.width, canvas.height);
  const dataURI = canvas.toDataURL();

  // Do something with the result, like overwrite original
  img.src = dataURI;
}

// Set the image source 
// (can also be a data-uri, extracted from form input)
img.src = '/images/example.png';

Using images from a different domain will require a crossorigin="anonymous" attribute on the <img> tag and a CORS-enabled server.

Here's what it looks like resizing a 180x180px image to 50x50px.

Using Images From Forms (bonus)#

There are a few extra steps needed to extract a usable image from an HTML form element. To demonstrate, we'll use this basic form with a single file input.

HTML Snippet
<form action="..." id="my-form">
  <input required type="file" accept="image/*" name="photo" />
  <input type="submit value="Submit" />
</form>

In order to use get an get a usable image from the form, we need to do the following steps:

  1. Intercept the form submission event
  2. Read the contents of the <input /> into a data URI
  3. Load the data URI into a new <img /> element
  4. Resize the image using <canvas>

Here's the code required to do each of these steps.

Intercept Form Submission#

We can bind to the submit event of the form, to intercept it and prevent it from being submitted.

JavaScript Snippet
const form = document.querySelector('#my-form');
form.addEventListener('submit', (e) => {
  e.preventDefault(); // Prevent submission
});

Extract Image as a Data URI#

To get the image data from the form input, we can use the FileReader class.

JavaScript Snippet
const reader = new FileReader();

reader.addEventListener('load', () => {
  const dataUri = reader.result;

  // Do something with data URI...
});

reader.readAsDataURL(field);

Create <img> From Data URI#

Now that we have a data URI for the selected image, we can create an image element from it. This looks similar to what we did with FileReader.

JavaScript Snippet
const imgEl = document.createElement('img');
imgEl.addEventListener('load', () => {
  // Do something with <img> ...
});
imgEl.src = dataUri;

Wrap-Up#

Now that we have a newly-resized image, we can upload it to our server backend knowing that it will require much less bandwidth than the original photo.

I've created a CodePen (and embedded at the start of this post) to demonstrate what we covered today. It's an interactive demo, so feel free to play around with it.

Happy coding 👋


Awesome, thanks for the feedback! 🤗

How did you like the article?