diff --git a/lib/media/converters/imagemagickService.ts b/lib/media/converters/imagemagickService.ts index 7b1e56b..c85ca1e 100644 --- a/lib/media/converters/imagemagickService.ts +++ b/lib/media/converters/imagemagickService.ts @@ -1,4 +1,5 @@ import { loadImageMagick } from '@/lib/media/wasm/wasmLoader'; +import { convertSvgToPng } from '../utils/fileUtils'; import type { ConversionOptions, ProgressCallback, ConversionResult } from '@/types/media'; /** @@ -13,6 +14,19 @@ export async function convertWithImageMagick( const startTime = Date.now(); try { + let inputFile = file; + const isSvg = file.type === 'image/svg+xml' || file.name.endsWith('.svg'); + + // Handle SVG inputs by pre-converting to PNG using browser Canvas + if (isSvg) { + if (onProgress) onProgress(5); + // If we have dimensions in options, use them, otherwise use a high-res default + const width = options.imageWidth || 1024; + const height = options.imageHeight || 1024; + const pngBlob = await convertSvgToPng(file, width, height); + inputFile = new File([pngBlob], file.name.replace(/\.svg$/i, '.png'), { type: 'image/png' }); + } + // Load ImageMagick instance await loadImageMagick(); diff --git a/lib/media/utils/fileUtils.ts b/lib/media/utils/fileUtils.ts index 75826aa..6a6fda9 100644 --- a/lib/media/utils/fileUtils.ts +++ b/lib/media/utils/fileUtils.ts @@ -112,3 +112,41 @@ export async function downloadBlobsAsZip(files: Array<{ blob: Blob; filename: st // Download ZIP downloadBlob(zipBlob, zipFilename); } + +/** + * Convert SVG file/blob to PNG blob using browser Canvas + */ +export async function convertSvgToPng(svgFile: File | Blob, width: number, height: number): Promise { + return new Promise((resolve, reject) => { + const url = URL.createObjectURL(svgFile); + const img = new Image(); + + img.onload = () => { + const canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + const ctx = canvas.getContext('2d'); + if (!ctx) { + URL.revokeObjectURL(url); + reject(new Error('Could not get canvas context')); + return; + } + ctx.drawImage(img, 0, 0, width, height); + canvas.toBlob((blob) => { + URL.revokeObjectURL(url); + if (blob) { + resolve(blob); + } else { + reject(new Error('Canvas toBlob failed')); + } + }, 'image/png'); + }; + + img.onerror = () => { + URL.revokeObjectURL(url); + reject(new Error('Failed to load SVG image')); + }; + + img.src = url; + }); +}