Reduce image size before upload

Reduce image size before upload

The trick is to scale to image to a lower resolution size and then save it as lower quality image.

References

  • https://stackoverflow.com/a/72728396
  • https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/file

Implementation

async function scaleImageBeforeUpload(file, maxSize = 1280, imgQuality = 0.8) {

    const image = new Image()
    image.src = URL.createObjectURL(file)

    await new Promise(res => (image.onload = res))
    const canvas = document.createElement("canvas")
    const context = canvas.getContext("2d", { alpha: true })

    // Caculate desired new width and height within maxSize.
    let width = image.width;
    let height = image.height;

    if (width > height) {
        if (width > maxSize) {
            height *= maxSize / width;
            width = maxSize;
        }
    } else {
        if (height > maxSize) {
            width *= maxSize / height;
            height = maxSize;
        }
    }

    // Draw new image with new dimensions.
    canvas.width = width;
    canvas.height = height;
    context.drawImage(image, 0, 0, width, height);

    // Save new image to lower quality image.
    return new Promise(resolve => {
        canvas.toBlob(blob => {
            const newImgFile = new File([blob], file.name, { type: "image/jpeg" }); // https://stackoverflow.com/a/64463046
            resolve(newImgFile);
        }, 'image/jpeg', imgQuality);
    });
}