feat: .dng support

This commit is contained in:
not-nullptr 2025-04-14 11:52:13 +01:00
parent 45ea828ddf
commit 2b2c9146c2
4 changed files with 56 additions and 3 deletions

View File

@ -10,7 +10,7 @@
"@fontsource/azeret-mono": "^5.1.1",
"@fontsource/lexend": "^5.1.2",
"@fontsource/radio-canada-big": "^5.1.1",
"@imagemagick/magick-wasm": "^0.0.32",
"@imagemagick/magick-wasm": "^0.0.34",
"client-zip": "^2.4.6",
"clsx": "^2.1.1",
"lucide-svelte": "^0.475.0",
@ -132,7 +132,7 @@
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.2", "", {}, "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ=="],
"@imagemagick/magick-wasm": ["@imagemagick/magick-wasm@0.0.32", "", {}, "sha512-+niNRuJk4ZPE9PDzBg19Kjyl+CEdAgaJBXQSFXmO1CTDoYOxrZ3DBdstfs1+8r77hjoiph+4Wu4qpldfcrKm7A=="],
"@imagemagick/magick-wasm": ["@imagemagick/magick-wasm@0.0.34", "", {}, "sha512-vSTe4cfR8U8r2Ityo6s3iRFVK903W4fhur3t/ixc6vLSAJXmqXC9cKXz2NkkDBUVU7ssJTYMiTKAb1S9RY+ZdQ=="],
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],

View File

@ -40,7 +40,7 @@
"@fontsource/azeret-mono": "^5.1.1",
"@fontsource/lexend": "^5.1.2",
"@fontsource/radio-canada-big": "^5.1.1",
"@imagemagick/magick-wasm": "^0.0.32",
"@imagemagick/magick-wasm": "^0.0.34",
"client-zip": "^2.4.6",
"clsx": "^2.1.1",
"lucide-svelte": "^0.475.0",

View File

@ -23,6 +23,7 @@ export class VipsConverter extends Converter {
".gif",
".hdr",
".jpe",
".dng",
".mat",
".pbm",
".pfm",

View File

@ -1,10 +1,24 @@
import Vips from "wasm-vips";
import {
initializeImageMagick,
MagickFormat,
MagickImage,
MagickReadSettings,
} from "@imagemagick/magick-wasm";
import wasm from "@imagemagick/magick-wasm/magick.wasm?url";
const vipsPromise = Vips({
dynamicLibraries: [],
});
const magickPromise = initializeImageMagick(new URL(wasm, import.meta.url));
const magickRequiredFormats = [".dng"];
const unsupportedFrom: string[] = [];
const unsupportedTo = [".dng"];
vipsPromise
.then(() => magickPromise)
.then(() => {
postMessage({ type: "loaded" });
})
@ -18,7 +32,45 @@ const handleMessage = async (message: any): Promise<any> => {
switch (message.type) {
case "convert": {
if (!message.to.startsWith(".")) message.to = `.${message.to}`;
if (unsupportedFrom.includes(message.input.from)) {
return {
type: "error",
error: `Unsupported input format ${message.input.from}`,
};
}
if (unsupportedTo.includes(message.to)) {
return {
type: "error",
error: `Unsupported output format ${message.to}`,
};
}
const buffer = await message.input.file.arrayBuffer();
if (
magickRequiredFormats.includes(message.input.from) ||
magickRequiredFormats.includes(message.to)
) {
const magick = MagickImage.create(
new Uint8Array(buffer),
new MagickReadSettings({
format: message.input.from
.slice(1)
.toUpperCase() as MagickFormat,
}),
);
const dngBuffer = await new Promise<Uint8Array>((resolve) =>
magick.write(message.to.slice(1).toUpperCase(), (data) => {
resolve(data);
}),
);
return {
type: "finished",
output: dngBuffer,
};
}
let image = vips.Image.newFromBuffer(buffer, "");
// check if animated image & keep it animated when converting