Leon4gr45/builder
0
1/**2 * Image compression utility for thumbnail uploads.3 * Loads a File into an Image, draws onto a canvas at max 640×3604 * (maintaining aspect ratio), and exports as JPEG base64.5 */6 7const MAX_WIDTH = 640;8const MAX_HEIGHT = 360;9const INITIAL_QUALITY = 0.7;10const FALLBACK_QUALITY = 0.5;11const MAX_SIZE_BYTES = 100_000; // 100 KB12 13export async function compressImage(file: File): Promise<string> {14 const bitmap = await createImageBitmap(file);15 16 // Calculate output dimensions maintaining aspect ratio17 let width = bitmap.width;18 let height = bitmap.height;19 20 if (width > MAX_WIDTH || height > MAX_HEIGHT) {21 const scale = Math.min(MAX_WIDTH / width, MAX_HEIGHT / height);22 width = Math.round(width * scale);23 height = Math.round(height * scale);24 }25 26 const canvas = document.createElement('canvas');27 canvas.width = width;28 canvas.height = height;29 30 const ctx = canvas.getContext('2d');31 if (!ctx) throw new Error('Failed to get canvas context');32 33 ctx.drawImage(bitmap, 0, 0, width, height);34 bitmap.close();35 36 // First attempt at normal quality37 let dataUrl = canvas.toDataURL('image/jpeg', INITIAL_QUALITY);38 39 // If too large, retry at lower quality40 if (dataUrl.length > MAX_SIZE_BYTES * 1.37) {41 // base64 is ~37% larger than raw bytes42 dataUrl = canvas.toDataURL('image/jpeg', FALLBACK_QUALITY);43 }44 45 return dataUrl;46}47 