lumeland / imagemagick-deno

Deno port of the WASM library for ImageMagick
https://deno.land/x/imagemagick_deno
44 stars 3 forks source link

Failing to convert any img larger than 5MB to avif #17

Closed OmarElfouly closed 1 week ago

OmarElfouly commented 2 weeks ago

https://sample-videos.com/download-sample-jpg-image.php

Using the images above and the sample code given I discovered that any file larger than 5 MB will create an image that is invalid.

import {
  ImageMagick,
  IMagickImage,
  initialize,
  MagickFormat,
} from "https://deno.land/x/imagemagick_deno/mod.ts";
import * as base64 from "https://denopkg.com/chiefbiiko/base64@master/mod.ts";

//https://sample-videos.com/download-sample-jpg-image.php
await initialize(); // make sure to initialize first!

const data: Uint8Array = await Deno.readFile("SampleJPGImage_20mbmb.jpg");

await ImageMagick.read(data, async (img: IMagickImage) => {
  await img.write(MagickFormat.Avif, (data: Uint8Array) =>
    Deno.writeFile("image-20mb.avif", data)
  );
});
oscarotero commented 2 weeks ago

This package is just a port of https://github.com/dlemstra/magick-wasm to make it work on Deno. But now Deno supports npm packages, so I'm not sure if this port is still useful.

Can you try to use the original NPM package? (you can import it with import * as magick from "npm:@imagemagick/magick-wasm).

OmarElfouly commented 2 weeks ago

Thank you for your quick reply! I have a question on how I should initialize on deno using the initializeImageMagick found in the npm package?

OmarElfouly commented 2 weeks ago

So far I've attempted to do so with the magick_native.wasm found on this project but i received the following error:

import {
  ImageMagick,
  IMagickImage,
  initializeImageMagick,
  MagickFormat,
  Magick,
} from "npm:@imagemagick/magick-wasm";

const wasm = await Deno.readFile("@imagemagick/magick-wasm/magick.wasm");
await initializeImageMagick(wasm);

Result:

failed to asynchronously prepare wasm: LinkError: WebAssembly.instantiate(): Import #108 "a" "ab": function import requires a callable
Aborted(LinkError: WebAssembly.instantiate(): Import #108 "a" "ab": function import requires a callable)
oscarotero commented 2 weeks ago

there's an example here: https://github.com/dlemstra/magick-wasm/issues/81#issuecomment-1845571997 Can you try it and confirm if it works?

OmarElfouly commented 1 week ago

there's an example here: dlemstra/magick-wasm#81 (comment) Can you try it and confirm if it works?

The issue with that example is it uses

await initializeImageMagick();

Which is a function that now expects 1 or 2 arguments.

function initializeImageMagick(wasmLocationDataOrAssembly: URL | ByteArray | WebAssembly.Module, configurationFiles?: IConfigurationFiles): Promise<void>;
oscarotero commented 1 week ago

This function has changed and now it requires a URL or a Int8Array with the content of the wasm file.

This should work:

import { initializeImageMagick } from "npm:@imagemagick/magick-wasm@0.0.30";

const wasmUrl = "https://cdn.jsdelivr.net/npm/@imagemagick/magick-wasm@0.0.30/dist/magick.wasm";
const response = await fetch(wasmUrl);
await initializeImageMagick(new Int8Array(await response.arrayBuffer()));
OmarElfouly commented 1 week ago

Thank you so much!

It works great. The only odd thing I noticed is that it takes a long time (~1.5mins) to convert a 10mb file to avif but this is perfect.

Does that mean that the issue with imagemagick_deno is that the wasm is outdated? I say this because one of my attempts was to use magick_native.wasm found at deno/src/wasm/magick_native.wasm as the source for initializeImageMagick

Also I just wanted to thank you again for your help!

oscarotero commented 1 week ago

The original NPM package is 2 or 3 versions ahead of this port, so maybe that affects. Maybe you can try sharp, which works fine with Deno and it's more performant (it's the library I'm already using).