The trick is to scale to image to a lower resolution size and then save it as lower quality image.
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);
});
}