Home Reference Source

src/utils/scaleImage.ts

type Format = 'image/png' | 'image/webp';

/**
 * Scales the image provided to the given width and height.
 * @param file A blob containing the image to scale.
 * @param width The width to scale the image to.
 * @param height The height to scale the image to.
 * @param format The format of the scaled image.
 * @returns A promise that resolves to a string containing the scaled image in a base64 representation.
 */
export async function scaleImage(file: Blob, width: number, height: number, format: Format = 'image/webp'): Promise<string> {
	return new Promise((resolve, reject) => {
		const image = new Image();
		image.onload = () => {
			URL.revokeObjectURL(image.src);
			const canvas = document.createElement('canvas');
			const dWidth = Math.min(image.width, width);
			const dHeight = Math.min(image.height, height);
			canvas.width = dWidth;
			canvas.height = dHeight;
			const sx = image.width > image.height ? (image.width - image.height) / 2 : 0;
			const sy = image.height > image.width ? (image.height - image.width) / 2 : 0;
			const sWidth = Math.min(image.width, image.height * width / height);
			const sHeight = Math.min(image.width * height / width, image.height);
			const context = canvas.getContext('2d');
			if (context) {
				context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, dWidth, dHeight);
				const base64Url = canvas.toDataURL(format);
				resolve(base64Url);
			} else {
				reject(new Error('Canvas is not supported'));
			}
		};
		image.src = URL.createObjectURL(file);
	});
}