Javascript module to be run in the web browser for image compression.
- 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.
open https://donaldcwl.github.io/browser-image-compression/example/basic.html
or check the "example" folder in this repo
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/[email protected]/dist/browser-image-compression.js
or
https://cdn.jsdelivr.net/npm/browser-image-compression@latest/dist/browser-image-compression.js
(can be used in framework like React, Angular, Vue etc)
(work with bundler like webpack and rollup)
import imageCompression from 'browser-image-compression';
or
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/browser-image-compression.js"></script>
<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);
});
}
If this project help you reduce time to develop, you can buy me a cup of coffee :)
// you should provide one of maxSizeMB, maxWidthOrHeight in the options
const options: 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)
// but, automatically reduce the size to smaller than the maximum Canvas size supported by each browser.
// Please check the Caveat part for details.
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: Options): Promise<File>
Each browser limits the maximum size of a Canvas object.
So, we resize the image to less than the maximum size that each browser restricts.
(However, the proportion/ratio
of the image remains.)
- 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, fileType?: string): HTMLCanvasElement | OffscreenCanvas
imageCompression.drawFileInCanvas(file: File, options?: Options): 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
IE / Edge |
Firefox |
Chrome |
Safari |
iOS Safari |
Opera |
---|---|---|---|---|---|
IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
The browser need to support "OffscreenCanvas" API in order to take advantage of non-blocking compression. If browser do not support "OffscreenCanvas" API, main thread is used instead. See https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas#browser_compatibility for browser compatibility of "OffscreenCanvas" API.
Typescript definitions are included in the package & referenced in the types
section of the package.json
- fork the repo and git clone it
- run
npm run watch
# it will watch code change in lib/ folder and generate js in dist/ folder - add/update code in lib/ folder
- try the code by opening example/development.html which will load the js in dist/ folder
- add/update test in test/ folder
npm run test
- push to your forked repo on github
- make a pull request to dev branch of this repo