dlemstra / magick-wasm

The WASM library for ImageMagick
Apache License 2.0
562 stars 38 forks source link

NoDecodeDelegateForThisImageFormat for ICO #96

Open pseudosavant opened 1 year ago

pseudosavant commented 1 year ago

magick-wasm version

0.22

Description

I am trying to use magick-wasm in a use case where I will be downloading/proxying a lot of favicons from the web in a Deno app. They will be in either PNG or legacy ICO/ICON format. Locally installed versions of imagemagick can handle these files fine but I'm having difficulty with magick-wasm.

Two example files:

Version and delegate information:

ImageMagick 7.1.1-11 Q8 x86_64 11ffa6eb4:20230529 https://imagemagick.org
Delegates: freetype heic jng jp2 jpeg jxl lcms lqr openexr png raw tiff webp xml zlib

Both of those files give an error about NoDecodeDelegateForThisImageFormat @ error/blob.c/BlobToImage/460. If I use the magick-image test page, it will load that PNG, but not the ICO.

This is the code I'm using:

import {
  initializeImageMagick,
  ImageMagick,
  Magick,
  Quantum,
  MagickFormat
} from './dist/index.mjs';

const wasm = await Deno.readFile(`./dist/magick.wasm`);
await initializeImageMagick(wasm);
console.log(Magick.imageMagickVersion);
console.log('Delegates:', Magick.delegates);
console.log('Features:', Magick.features);
console.log('Supported Formats:', Magick.supportedFormats);

const iconURL = 'https://pseudosavant.com/homemarks/favicon-1.1.0.ico';
const pngURL = 'https://pseudosavant.com/homemarks/images/favicon-144-1.0.png';
const iconFetch = await fetch(iconURL);

if (iconFetch.ok) {
  const iconData = await iconFetch.arrayBuffer();
  console.log(iconData);

  await ImageMagick.read(iconData, (img) => {
    console.log(img);
  });
}

Questions:

  1. Am I initializing this wrong?
  2. Do I need to compile magick-wasm with different flags to include PNG and ICO support?

Steps to Reproduce

  1. Use NPM to retrieve dist folder for 0.22
  2. Use Deno code below with the ICO or PNG URLs:
    
    import {
    initializeImageMagick,
    ImageMagick,
    Magick,
    Quantum,
    MagickFormat
    } from './dist/index.mjs';

const wasm = await Deno.readFile(./dist/magick.wasm); await initializeImageMagick(wasm); console.log(Magick.imageMagickVersion); console.log('Delegates:', Magick.delegates); console.log('Features:', Magick.features); console.log('Supported Formats:', Magick.supportedFormats);

const iconURL = 'https://pseudosavant.com/homemarks/favicon-1.1.0.ico'; const pngURL = 'https://pseudosavant.com/homemarks/images/favicon-144-1.0.png'; const iconFetch = await fetch(iconURL);

if (iconFetch.ok) { const iconData = await iconFetch.arrayBuffer(); console.log(iconData);

await ImageMagick.read(iconData, (img) => { console.log(img); }); }



### Images

_No response_
dlemstra commented 1 year ago

The ico format does not contain a header that will tell us that it is an ico. And that means that you will need to tell ImageMagick the format:

await ImageMagick.read(iconData, MagickFormat.Ico, (img) => {
pseudosavant commented 1 year ago

Thank you! Does the convert cli do extra detection to handle ICO files? I've never had to tell imagemagick it was an icon from the CLI. It is easy enough for me to check the magic bytes at the beginning of the array to determine if I need to handle it like an ICO though.

Adding MagickFormat.Ico did get me past that error, but now I'm experiencing this:

Error - ImproperImageHeader `' @ error/icon.c/ReadICONImage/233
dlemstra commented 1 year ago

The cli uses the file extension because the ico format has no magic bytes. Not sure how to add that to this api yet but that might be something support could be added for in the future

And if I remember correctly I was able to read your file without any issues. Will give it a try with your code later tonight to figure out what I did differently.