fix(media): handle SVG inputs using browser Canvas pre-conversion for ImageMagick WASM
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { loadImageMagick } from '@/lib/media/wasm/wasmLoader';
|
import { loadImageMagick } from '@/lib/media/wasm/wasmLoader';
|
||||||
|
import { convertSvgToPng } from '../utils/fileUtils';
|
||||||
import type { ConversionOptions, ProgressCallback, ConversionResult } from '@/types/media';
|
import type { ConversionOptions, ProgressCallback, ConversionResult } from '@/types/media';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13,6 +14,19 @@ export async function convertWithImageMagick(
|
|||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
|
||||||
try {
|
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
|
// Load ImageMagick instance
|
||||||
await loadImageMagick();
|
await loadImageMagick();
|
||||||
|
|
||||||
|
|||||||
@@ -112,3 +112,41 @@ export async function downloadBlobsAsZip(files: Array<{ blob: Blob; filename: st
|
|||||||
// Download ZIP
|
// Download ZIP
|
||||||
downloadBlob(zipBlob, zipFilename);
|
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<Blob> {
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user