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 {
// Load ImageMagick instance
const ImageMagick = await loadImageMagick();
await loadImageMagick();
// Report initial progress
if (onProgress) onProgress(10);
@@ -26,21 +26,55 @@ export async function convertWithImageMagick(
if (onProgress) onProgress(30);
// Import ImageMagick functions
const IM = await import('@imagemagick/magick-wasm');
const { ImageMagick } = await import('@imagemagick/magick-wasm');
// Determine output format
const magickFormat = getMagickFormat(outputFormat);
if (onProgress) onProgress(40);
// Get output format enum
const outputFormatEnum = await getMagickFormatEnum(outputFormat);
if (onProgress) onProgress(50);
// Convert image - Note: This is a placeholder implementation
// The actual ImageMagick WASM API may differ
const result = inputData; // Placeholder: just return input for now
// Convert image using ImageMagick
let result: Uint8Array;
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
const blob = new Blob([result as BlobPart], { type: getMimeType(outputFormat) });
const blob = new Blob([result! as BlobPart], { type: getMimeType(outputFormat) });
if (onProgress) onProgress(100);
@@ -65,20 +99,21 @@ export async function convertWithImageMagick(
/**
* Get ImageMagick format enum
*/
function getMagickFormat(format: string): any {
// This is a placeholder - actual implementation would use MagickFormat enum
const formatMap: Record<string, string> = {
png: 'Png',
jpg: 'Jpeg',
jpeg: 'Jpeg',
webp: 'WebP',
gif: 'Gif',
bmp: 'Bmp',
tiff: 'Tiff',
svg: 'Svg',
async function getMagickFormatEnum(format: string): Promise<any> {
const { MagickFormat } = await import('@imagemagick/magick-wasm');
const formatMap: Record<string, any> = {
png: MagickFormat.Png,
jpg: MagickFormat.Jpg,
jpeg: MagickFormat.Jpg,
webp: MagickFormat.WebP,
gif: MagickFormat.Gif,
bmp: MagickFormat.Bmp,
tiff: MagickFormat.Tiff,
svg: MagickFormat.Svg,
};
return formatMap[format.toLowerCase()] || format;
return formatMap[format.toLowerCase()] || MagickFormat.Png;
}
/**