Compress images with Javascript

These days, most of the photos generated by our devices are quite large in resolution and in size. As developers, we may not need large images (>5mb) especially if you’re using it for a profile picture or so. A common solution so far was to resize the image after it was uploaded to the server. How about doing this at the client side and compressing the image before it reaches the server? Let’s see how to compress images with pure javascript and the advantages of doing so.

Javascript image compression
Advantages of compressing images at the client side:

  • Decreasing image size means sending lesser data to the server resulting in faster uploads
  • Processing is done at the client side saving you some processing cycles at the server
  • Fine control over the image resolution and image quality
  • Supports all major image formats (.jpg, .png, .webp, .gif, …)

How to Compress images with Javascript ?

Compressing images with Javascript has become quite simple due to the Canvas element. The trick is to first convert the image file into Blob data which can then be passed to the canvas element. The canvas API can then be used to be resize, compress the image as needed before being sent to the server. That’s it. Here’s a neat example of the same.

You sure can use the code found at the aforementioned link, however for those looking to avoid rewriting code, here’s a list of libraries to compress images with pure javascript.


1. Compressorjs

Compressorjs uses the browser’s native canvas.toBlob API which also means that the compression is lossy. Size-wise it stands at around 3.5 KB minzipped. It is a well maintained library having good community support. Its usage is also pretty straightforward.

Here’s a live Demo to see it and a small code snippet to get it working –

// install
npm install compressorjs

// usage
new Compressor(file[, options])

2. Image-conversion

We like Image-conversion library due to the fact that it allows you to set a maximum output file size and that it exposes helper methods to covert an image to canvas or to get the dataURL from the canvas. As you might have guessed, just like the previous package, image-coversion too performs lossy compression using the Javascript’s native Canvas API. It is a pretty light-weight library standing at about 2 KB minzipped. As of Aug 2021, it is well maintained and has good community and browser support.

Here’s a Demo of the same, followed by a small snippet demonstrating its setup

// install 
npm i image-conversion --save

// usage
import * as imageConversion from 'image-conversion';

imageConversion.compressAccurately(file, 200); // compress to 200 kB
imageConversion.compress(file, 0.9);           // compress image by quality (0.1 - 0.9)

3. Browser-image-compression

Browser image compression library is also a good alternative, however it is a bit heavy in terms of weight standing at about 50 Kb minzipped. If that’s not an issue for you then this can be a good alternative as it allows offloading processing to web workers through its options thereby keeping the main thread ready for other tasks. It has good browser support and is well maintained too. Again, as the previous libs, expect lossy compression from it.

Here’s the link to the Demo followed by a small code snippet.

// install
npm install browser-image-compression --save

// usage
import imageCompression from 'browser-image-compression';

imageCompression(file: File, { 
  maxSizeMB: number,          // (default: Number.POSITIVE_INFINITY)
  maxWidthOrHeight: number,   // compressedFile will scale down by ratio to a point that width or height is smaller than maxWidthOrHeight (default: undefined)
                              // but, automatically reduce the size to smaller than the maximum Canvas size supported by each browser.
                              // Do not forget to check the Caveat part on the official doc.
  onProgress: Function,       // optional, a function takes one progress argument (percentage from 0 to 100) 
  useWebWorker: boolean,      // optional, use multi-thread web worker, fallback to run in main-thread (default: true)

  // advanced options
  maxIteration: number,       // optional, max number of iteration to compress the image (default: 10)
  exifOrientation: number,    // optional, see https://stackoverflow.com/a/32490603/10395024
  fileType: string,           // optional, fileType override
  initialQuality: number      // optional, initial quality value between 0 and 1 (default: 1)
})

A worthy mention – Photon

Photon is an image processing library made in wasm that can be run over the web. Check out its Demo to get a gist of its capability. Besides resizing there are a lot other features like filters, transformations, corrections, etc. available to play with.


Update: Dec 2022

Another interesting contender – Squoosh

Squoosh is a popular image compressing web app maintained and open-sourced by google. It also has an API/CLI tool to compress multiple images or to integrate the app within your own JS app.

Hope that helps 🙂


References

Leave a Reply