import imageCompression from 'browser-image-compression'; /** * Interface for the processed image result */ export interface ProcessedImage { file: File; // The compressed WebP file (ready for Supabase storage) base64: string; // The Base64 string (ready for LLM API calls) originalFile: File; // Pass through the original file } /** * Converts a File or Blob object to a Base64 string. * * @param file - The file or blob to convert * @returns A promise that resolves to the Base64 string */ export function fileToBase64(file: File | Blob): Promise { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { if (typeof reader.result === 'string') { resolve(reader.result); } else { reject(new Error('Failed to convert file to Base64 string')); } }; reader.onerror = (error) => reject(error); reader.readAsDataURL(file); }); } /** * Processes an image file for AI analysis and storage. * * Logic: * 1. Resize to max 1024x1024 (maintains aspect ratio) * 2. Convert to WebP format * 3. Limit file size to approx 0.4MB * 4. Uses WebWorker to prevent UI freezing * * @param file - The raw File object from an HTML input * @returns A promise that resolves to a ProcessedImage object */ export async function processImageForAI(file: File): Promise { const options = { maxSizeMB: 0.4, maxWidthOrHeight: 1024, useWebWorker: true, fileType: 'image/webp' }; try { console.log(`[processImageForAI] Original size: ${(file.size / 1024 / 1024).toFixed(2)} MB`); // Compress the image const compressedBlob = await imageCompression(file, options); // Create a new File object from the compressed Blob with .webp extension const compressedFile = new File( [compressedBlob], file.name.replace(/\.[^/.]+$/, "") + ".webp", { type: 'image/webp' } ); console.log(`[processImageForAI] Compressed size: ${(compressedFile.size / 1024 / 1024).toFixed(2)} MB`); // Convert to Base64 for AI API calls const base64 = await fileToBase64(compressedFile); return { file: compressedFile, base64, originalFile: file }; } catch (error) { console.error('[processImageForAI] Error processing image:', error); throw error; } }