fix: implement actual ImageMagick WASM conversion with quality settings

Previously, the ImageMagick service was just a placeholder that returned
the input data unchanged. This caused PNG to WebP conversions to have
the same file size.

Changes:
- Properly implement ImageMagick.read() with conversion logic
- Apply imageQuality option to control compression
- Apply imageWidth/imageHeight options with aspect ratio preservation
- Use correct MagickFormat enum values for output formats
- Fix write() method signature (format comes before callback)
- Remove unnecessary initializeImageMagick() call

Image conversion now properly applies:
- Quality settings (1-100%)
- Resolution/resize options
- Format-specific compression

This fixes the issue where quality settings had no effect on output
file size. Users will now see proper file size reduction when using
lower quality settings or converting to compressed formats like WebP.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-17 11:56:54 +01:00
parent f253285c25
commit 78394b7e97

View File

@@ -14,7 +14,7 @@ export async function convertWithImageMagick(
try { try {
// Load ImageMagick instance // Load ImageMagick instance
const ImageMagick = await loadImageMagick(); await loadImageMagick();
// Report initial progress // Report initial progress
if (onProgress) onProgress(10); if (onProgress) onProgress(10);
@@ -26,21 +26,55 @@ export async function convertWithImageMagick(
if (onProgress) onProgress(30); if (onProgress) onProgress(30);
// Import ImageMagick functions // Import ImageMagick functions
const IM = await import('@imagemagick/magick-wasm'); const { ImageMagick } = await import('@imagemagick/magick-wasm');
// Determine output format if (onProgress) onProgress(40);
const magickFormat = getMagickFormat(outputFormat);
// Get output format enum
const outputFormatEnum = await getMagickFormatEnum(outputFormat);
if (onProgress) onProgress(50); if (onProgress) onProgress(50);
// Convert image - Note: This is a placeholder implementation // Convert image using ImageMagick
// The actual ImageMagick WASM API may differ let result: Uint8Array;
const result = inputData; // Placeholder: just return input for now
if (onProgress) onProgress(90); await ImageMagick.read(inputData, (image) => {
// Apply quality setting if specified
if (options.imageQuality !== undefined) {
image.quality = options.imageQuality;
}
// Apply resize if specified
if (options.imageWidth || options.imageHeight) {
const width = options.imageWidth || 0;
const height = options.imageHeight || 0;
if (width > 0 && height > 0) {
// Both dimensions specified
image.resize(width, height);
} else if (width > 0) {
// Only width specified, maintain aspect ratio
const aspectRatio = image.height / image.width;
image.resize(width, Math.round(width * aspectRatio));
} else if (height > 0) {
// Only height specified, maintain aspect ratio
const aspectRatio = image.width / image.height;
image.resize(Math.round(height * aspectRatio), height);
}
}
if (onProgress) onProgress(70);
// Write to output format
image.write(outputFormatEnum, (data) => {
result = data;
});
if (onProgress) onProgress(90);
});
// Create blob from result // Create blob from result
const blob = new Blob([result as BlobPart], { type: getMimeType(outputFormat) }); const blob = new Blob([result! as BlobPart], { type: getMimeType(outputFormat) });
if (onProgress) onProgress(100); if (onProgress) onProgress(100);
@@ -65,20 +99,21 @@ export async function convertWithImageMagick(
/** /**
* Get ImageMagick format enum * Get ImageMagick format enum
*/ */
function getMagickFormat(format: string): any { async function getMagickFormatEnum(format: string): Promise<any> {
// This is a placeholder - actual implementation would use MagickFormat enum const { MagickFormat } = await import('@imagemagick/magick-wasm');
const formatMap: Record<string, string> = {
png: 'Png', const formatMap: Record<string, any> = {
jpg: 'Jpeg', png: MagickFormat.Png,
jpeg: 'Jpeg', jpg: MagickFormat.Jpg,
webp: 'WebP', jpeg: MagickFormat.Jpg,
gif: 'Gif', webp: MagickFormat.WebP,
bmp: 'Bmp', gif: MagickFormat.Gif,
tiff: 'Tiff', bmp: MagickFormat.Bmp,
svg: 'Svg', tiff: MagickFormat.Tiff,
svg: MagickFormat.Svg,
}; };
return formatMap[format.toLowerCase()] || format; return formatMap[format.toLowerCase()] || MagickFormat.Png;
} }
/** /**