splitwise / src /lib /client /downscale.ts
assafvayner's picture
assafvayner HF Staff
feat(ui): add expense form with live split editor and photo upload
4ae345a
Raw
History Blame Contribute Delete
1.06 kB
/**
* Downscales an image file in the browser to at most `maxEdge` px on its longest side
* and re-encodes it as JPEG. Returns null when no processing is needed or possible.
*/
export async function downscaleImage(file: File, maxEdge = 1600, quality = 0.85): Promise<Blob | null> {
if (typeof createImageBitmap === 'undefined' || typeof document === 'undefined') return null;
try {
const bitmap = await createImageBitmap(file);
const scale = Math.min(1, maxEdge / Math.max(bitmap.width, bitmap.height));
if (scale === 1 && file.type === 'image/jpeg') {
bitmap.close();
return null;
}
const canvas = document.createElement('canvas');
canvas.width = Math.max(1, Math.round(bitmap.width * scale));
canvas.height = Math.max(1, Math.round(bitmap.height * scale));
const ctx = canvas.getContext('2d');
if (!ctx) return null;
ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
bitmap.close();
return await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, 'image/jpeg', quality));
} catch {
return null;
}
}