Files
Dramlog-Prod/src/utils/image-processing.ts

81 lines
2.5 KiB
TypeScript

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<string> {
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<ProcessedImage> {
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;
}
}