fix: imagemagick format conversion failures

This commit is contained in:
Maya 2026-06-04 12:27:15 +03:00
parent 84c36aa0a1
commit 058f16af61
No known key found for this signature in database
2 changed files with 26 additions and 34 deletions

View File

@ -97,7 +97,6 @@ export const imageFormats = [
new FormatInfo("png64", true, true), new FormatInfo("png64", true, true),
new FormatInfo("png8", true, true), new FormatInfo("png8", true, true),
new FormatInfo("ps", false, true), new FormatInfo("ps", false, true),
new FormatInfo("ps1", false, true),
new FormatInfo("ps2", false, true), new FormatInfo("ps2", false, true),
new FormatInfo("ps3", false, true), new FormatInfo("ps3", false, true),
new FormatInfo("psb", true, true), new FormatInfo("psb", true, true),

View File

@ -55,9 +55,11 @@ const handleMessage = async (
message.to = message.to.toLowerCase(); message.to = message.to.toLowerCase();
if (message.to === ".jfif") message.to = ".jpeg"; if (message.to === ".jfif") message.to = ".jpeg";
let to = message.input.to;
let from = message.input.from; let from = message.input.from;
if (from === ".jfif") from = ".jpeg"; if (from === ".jfif") from = ".jpeg";
if (from === ".fit") from = ".fits"; if (from === ".fit") from = ".fits";
if (to === ".fit") to = ".fits";
console.log(JSON.stringify(message, null, 2)); console.log(JSON.stringify(message, null, 2));
const conversionSettings = JSON.parse( const conversionSettings = JSON.parse(
@ -67,38 +69,12 @@ const handleMessage = async (
const specialResult = await handleSpecialOutput( const specialResult = await handleSpecialOutput(
from, from,
message.to, to,
buffer, buffer,
conversionSettings, conversionSettings,
); );
if (specialResult) return specialResult; if (specialResult) return specialResult;
// build frames of animated formats (webp/gif)
// APNG does not work on magick-wasm since it needs ffmpeg built-in (not in magick-wasm) - handle in ffmpeg
if (
(from === ".webp" || from === ".gif") &&
(message.to === ".gif" || message.to === ".webp")
) {
const collection = MagickImageCollection.create(
new Uint8Array(buffer),
);
const format =
message.to === ".gif"
? MagickFormat.Gif
: MagickFormat.WebP;
const result = await new Promise<Uint8Array>((resolve) => {
collection.write(format, (output) => {
resolve(structuredClone(output));
});
});
collection.dispose();
return {
type: "finished",
output: result,
};
}
const parsedInput = await handleSpecialInput(from, buffer); const parsedInput = await handleSpecialInput(from, buffer);
const img = parsedInput const img = parsedInput
? MagickImage.create( ? MagickImage.create(
@ -112,11 +88,7 @@ const handleMessage = async (
}), }),
); );
const converted = await magickConvert( const converted = await magickConvert(img, to, conversionSettings);
img,
message.to,
conversionSettings,
);
return { return {
type: "finished", type: "finished",
@ -183,6 +155,27 @@ const handleSpecialOutput = async (
buffer: ArrayBuffer, buffer: ArrayBuffer,
conversionSettings: ConversionSettings, conversionSettings: ConversionSettings,
): Promise<Partial<WorkerMessage> | null> => { ): Promise<Partial<WorkerMessage> | null> => {
// build frames of animated formats (webp/gif)
// APNG does not work on magick-wasm since it needs ffmpeg built-in (not in magick-wasm) - handle in ffmpeg
if (
(from === ".webp" || from === ".gif") &&
(to === ".gif" || to === ".webp")
) {
const collection = MagickImageCollection.create(new Uint8Array(buffer));
const format = to === ".gif" ? MagickFormat.Gif : MagickFormat.WebP;
const result = await new Promise<Uint8Array>((resolve) => {
collection.write(format, (output) => {
resolve(structuredClone(output));
});
});
collection.dispose();
return {
type: "finished",
output: result,
};
}
if (from === ".ico") { if (from === ".ico") {
const imgs = MagickImageCollection.create(); const imgs = MagickImageCollection.create();
imgs.read( imgs.read(
@ -225,7 +218,7 @@ const handleSpecialOutput = async (
} }
if (from === ".ani") { if (from === ".ani") {
console.log("Parsing ANI file"); console.log("Parsing ANI file");
try { try {
const { parseAni } = await loadAniHelpers(); const { parseAni } = await loadAniHelpers();
const parsedAni = parseAni(new Uint8Array(buffer)); const parsedAni = parseAni(new Uint8Array(buffer));