import sharp from 'sharp'; export interface OptimizationResult { buffer: Buffer; mimetype: string; } export class ImageOptimizer { /** * Optimizes an image: converts to WebP, strips metadata, * and applies a 1:1 Smart Crop if needed. */ static async optimize( buffer: Buffer, category: string = 'media', options: { aspect?: string; size?: number } = {} ): Promise { try { let pipeline = sharp(buffer); const metadata = await pipeline.metadata(); if (!metadata.format) return { buffer, mimetype: 'application/octet-stream' }; // 1. Identify Target Size // Default sizes based on category let targetSize = options.size || 1024; if (category === 'partners' || category === 'users') targetSize = 400; if (category === 'benefits') targetSize = 800; // 2. Smart Crop 1:1 if aspect=1:1 is requested or implied by category const shouldCrop = options.aspect === '1:1' || ['partners', 'users'].includes(category); if (shouldCrop) { pipeline = pipeline.resize({ width: targetSize, height: targetSize, fit: sharp.fit.cover, position: sharp.strategy.entropy // Smart focal point detection }); } else { // Resize without cropping if it's too large pipeline = pipeline.resize({ width: targetSize, withoutEnlargement: true, fit: sharp.fit.inside }); } // 3. Convert to WebP & Strip Metadata const optimizedBuffer = await pipeline .webp({ quality: 85, effort: 4 }) .toBuffer(); return { buffer: optimizedBuffer, mimetype: 'image/webp' }; } catch (err) { console.error('[SmartVision] Optimization failed:', err); return { buffer, mimetype: 'image/jpeg' }; // Fallback } } }