import { resizeImage } from '../media/converters/imagemagickService'; import type { FaviconIcon, FaviconSet, FaviconOptions } from '@/types/favicon'; export const ICON_CONFIGS = [ { name: 'favicon-16x16.png', width: 16, height: 16 }, { name: 'favicon-32x32.png', width: 32, height: 32 }, { name: 'apple-touch-icon.png', width: 180, height: 180 }, { name: 'android-chrome-192x192.png', width: 192, height: 192 }, { name: 'android-chrome-512x512.png', width: 512, height: 512 }, { name: 'favicon.ico', width: 48, height: 48 }, // Simple ICO fallback ]; export async function generateFaviconSet( file: File, options: FaviconOptions, onProgress?: (progress: number) => void ): Promise { const icons: FaviconIcon[] = []; const totalSteps = ICON_CONFIGS.length; for (let i = 0; i < ICON_CONFIGS.length; i++) { const config = ICON_CONFIGS[i]; const format = config.name.endsWith('.ico') ? 'ico' : 'png'; const result = await resizeImage(file, config.width, config.height, format); if (result.success && result.blob) { icons.push({ name: config.name, width: config.width, height: config.height, size: result.blob.size, blob: result.blob, previewUrl: URL.createObjectURL(result.blob), }); } if (onProgress) { onProgress(Math.round(((i + 1) / totalSteps) * 100)); } } const manifest = generateManifest(options); const htmlCode = generateHtmlCode(options); return { icons, manifest, htmlCode, }; } function generateManifest(options: FaviconOptions): string { const manifest = { name: options.name, short_name: options.shortName, icons: [ { src: '/android-chrome-192x192.png', sizes: '192x192', type: 'image/png', }, { src: '/android-chrome-512x512.png', sizes: '512x512', type: 'image/png', }, ], theme_color: options.themeColor, background_color: options.backgroundColor, display: 'standalone', }; return JSON.stringify(manifest, null, 2); } function generateHtmlCode(options: FaviconOptions): string { return ` `.trim(); }