Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

browser-images-compression

Donaldcwl467MIT2.1.0TypeScript support: included

Compress images in the browser

image compression, browser, image processing, reduce resolution, reduce size

readme

Browser Image Compression

npm npm npm

Javascript module to be run in the web browser for image compression.

Features

  • You can use this module to compress jpeg and png image by reducing resolution or storage size before uploading to application server to save bandwidth.
  • Multi-thread (web worker) non-blocking compression are supported through options.

Install

You can download imageCompression from the dist folder. Alternatively, you can install it via yarn or npm

npm install browser-image-compression --save
or
yarn add browser-image-compression

or use a CDN like delivrjs:

https://cdn.jsdelivr.net/npm/browser-image-compression@1.0.13/dist/browser-image-compression.js
or
https://cdn.jsdelivr.net/npm/browser-image-compression@latest/dist/browser-image-compression.js

How to use this module in your project?

Use as ES module

(can be used in framework like React, Angular, Vue etc)

(work with bundler like webpack and rollup)

import imageCompression from 'browser-image-compression';

or

In html file

<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/browser-image-compression@1.0.13/dist/browser-image-compression.js"></script>

API

Main function

// you should provide one of maxSizeMB, maxWidthOrHeight in the options
const options = { 
  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)
  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)

  // following options are for advanced users
  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)
}

imageCompression(file: File, options): Promise<File>

Helper function

  • for advanced users only, most users won't need to use the helper functions
    imageCompression.getDataUrlFromFile(file: File): Promise<base64 encoded string>
    imageCompression.getFilefromDataUrl(dataUrl: string, filename: string, lastModified?: number): Promise<File>
    imageCompression.loadImage(url: string): Promise<HTMLImageElement>
    imageCompression.drawImageInCanvas(img: HTMLImageElement): HTMLCanvasElement | OffscreenCanvas
    imageCompression.drawFileInCanvas(file: File): Promise<[ImageBitmap | HTMLImageElement, HTMLCanvasElement | OffscreenCanvas]>
    imageCompression.canvasToFile(canvas: HTMLCanvasElement | OffscreenCanvas, fileType: string, fileName: string, fileLastModified: number, quality?: number): Promise<File>
    imageCompression.getExifOrientation(file: File): Promise<number> // based on https://stackoverflow.com/a/32490603/10395024

Usage

<input type="file" accept="image/*" onchange="handleImageUpload(event);">

async await syntax:

async function handleImageUpload(event) {

  const imageFile = event.target.files[0];
  console.log('originalFile instanceof Blob', imageFile instanceof Blob); // true
  console.log(`originalFile size ${imageFile.size / 1024 / 1024} MB`);

  const options = {
    maxSizeMB: 1,
    maxWidthOrHeight: 1920,
    useWebWorker: true
  }
  try {
    const compressedFile = await imageCompression(imageFile, options);
    console.log('compressedFile instanceof Blob', compressedFile instanceof Blob); // true
    console.log(`compressedFile size ${compressedFile.size / 1024 / 1024} MB`); // smaller than maxSizeMB

    await uploadToServer(compressedFile); // write your own logic
  } catch (error) {
    console.log(error);
  }

}

Promise.then().catch() syntax:

function handleImageUpload(event) {

  var imageFile = event.target.files[0];
  console.log('originalFile instanceof Blob', imageFile instanceof Blob); // true
  console.log(`originalFile size ${imageFile.size / 1024 / 1024} MB`);

  var options = {
    maxSizeMB: 1,
    maxWidthOrHeight: 1920,
    useWebWorker: true
  }
  imageCompression(imageFile, options)
    .then(function (compressedFile) {
      console.log('compressedFile instanceof Blob', compressedFile instanceof Blob); // true
      console.log(`compressedFile size ${compressedFile.size / 1024 / 1024} MB`); // smaller than maxSizeMB

      return uploadToServer(compressedFile); // write your own logic
    })
    .catch(function (error) {
      console.log(error.message);
    });
}

Demo / Example

open https://donaldcwl.github.io/browser-image-compression/example/basic.html

or check the "example" folder in this repo

Browsers support

IE / Edge
IE / Edge
Firefox
Firefox
Chrome
Chrome
Safari
Safari
Opera
Opera
Chrome for Android
Chrome for Android
IE10, IE11, Edge last 2 versions last 2 versions last 2 versions last 2 versions last 2 versions

IE support

Promise API is being used in this library. If you need to support browser that do not support Promise like IE. You can include the Promise polyfill in your project.

See: https://github.com/taylorhakes/promise-polyfill

You can include the following script to load the Promise polyfill:

<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script>

Typescript type definitions

Typescript definitions are included in the package & referenced in the types section of the package.json

Contribution

  1. fork the repo and git clone it
  2. run npm run watch # it will watch code change in lib/ folder and generate js in dist/ folder
  3. add/update code in lib/ folder
  4. try the code by opening example/development.html which will load the js in dist/ folder
  5. add/update test in test/ folder
  6. npm run test
  7. push to your forked repo on github
  8. make a pull request to this repo

changelog

v1.0.14 (6 Jan 2021)

  • updated: use UZIP to compress PNG image instead of Canvas
  • fixed: PNG transparent background become black after compression #84, #76
  • fixed: progress jump back to 0 when Web Worker failback to main thread #90

v1.0.13 (8 Nov 2020)

  • added: new option for setting initial quality level #64, #78
  • fixed: options object being altered by the compress func #71
  • fixed: issue with output size of png compression #57

v1.0.12 (4 June 2020)

  • fixed: issue with SSR #58

v1.0.11 (8 May 2020)

  • fixed: issue with IE support #38 #23

v1.0.10 (7 May 2020)

  • fixed: issue in Web Worker when onProgress is undefined #50
  • fixed: handle behavior change of exif orientation in iOS 13.4.1 and Safari 13.1 Desktop #52
  • updated: typescript type definitions to resolve #54

v1.0.9 (25 Mar 2020)

  • updated: compression becomes less aggressive, output file is closer to the 'maxWidthOrHeight' and/or 'maxSizeMB' in config
  • fixed: file size increased in specific situation

v1.0.8 (16 Mar 2020)

  • added: support for Server Side Rendering (SSR)
  • updated: ts type file

v1.0.7 (15 Mar 2020)

  • added: onProgress function in options for compression progress updates
  • added: allow fileType override
  • added: ts type file
  • updated: useWebWorker default set to false
  • fixed: garbage clean canvas for safari
  • fixed: issue in Cordova support
  • fixed: issue in IE browser
  • fixed: other issues

v1.0.6 (5 July 2019)

  • fixed: exif orientation do not work in some situations

v1.0.5 (1 June 2019)

  • added: support for cordova project that uses cordova-plugin-file
  • optimized: follow image exif orientation even though image do not required to compress or resize
  • fixed: error may throw on iPhone Safari because of OffscreenCanvas cannot get 2d context
  • fixed: exif orientation do not work in some situations

v1.0.2 (8 Apr 2019)

  • fixed: bug related to image orientation and squeezing

v1.0.1 (8 Mar 2019)

  • fixed: bug related to wrong image output resolution in some cases

v1.0.0 (6 Feb 2019)

  • breaking change: change "imageCompression" function signature
  • optimized: use of OffscreenCanvas when support, fallback to document.createElement('canvas')
  • optimized: use createImageBitmap when support, fallback to FileReader readAsDataURL
  • added: support web worker
  • added: follows image exif orientation