Skip to content

Instantly share code, notes, and snippets.

@nwaughachukwuma
Last active January 14, 2023 04:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nwaughachukwuma/678c20381a9085d1cd429c380e54e474 to your computer and use it in GitHub Desktop.
Save nwaughachukwuma/678c20381a9085d1cd429c380e54e474 to your computer and use it in GitHub Desktop.
Compress any image file before upload using imageBitmap and canvas
// See compatibility table for .toBlob() Method
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob#browser_compatibility
interface Option {
type: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/bmp' | 'image/gif';
quality?: number;
}
async function compressImage(file: File, option: Option) {
if (!file.type.startsWith('image')) {
throw new Error('File is not an image');
} else if (file.type.startsWith('image/svg')) {
return file
}
const imageBitmap = await createImageBitmap(file);
const canvas = document.createElement('canvas');
canvas.width = imageBitmap.width;
canvas.height = imageBitmap.height;
const ctx = canvas.getContext('2d');
if (!ctx) return file;
ctx.drawImage(imageBitmap, 0, 0);
const quality = option.quality || 1;
const blob = await new Promise<Blob | null>((resolve) =>
canvas.toBlob(resolve, option.type, quality)
);
// clean-up
canvas.remove()
imageBitmap.close()
if (!blob) return file;
console.log('Compressed image from', file.size, 'to', blob.size)
return new File([blob], file.name, {
type: option.type,
lastModified: Date.now()
});
}
// example
async function uploadImage(fileList: FileList | null) {
if (!fileList) return;
const file = fileList[0];
const compressedFile = await compressImage(file, { quality: 0.6, type: 'image/jpeg' });
// upload your image here
}
@ebeloded
Copy link

Nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment