Running ImageMagick wand library in WASM.
Try it here ppyne.github.io/imagick.
- ImageMagick Legacy version 6.9.12-66 (tar.gz present in the repo)
- libwebp 1.2.4 (optional, tar.gz present in the repo)
- libjpeg v8c (optional, tar.gz present in the repo)
- openjpeg 2.5.0 (optional, tar.gz present in the repo)
- zlib 1.2.12 (optional, tar.gz present in the repo)
- libpng 1.6.37 (optional, tar.gz present in the repo)
- for avif and heic support libheif 1.13.0, aom 1.0.0, dav1d 0.7.1, x265 3.4, libde265 1.0.9 (all this is optional, tar.gz archives are present in the repo)
- FFTW 3.3.10 (optional, tar.gz present in the repo)
- Emscripten SDK version 3.1.20
- A Unix like environment (Mac or Linux is fine) with bash
- Essential GNU building tools like make, cmake, meson, ninja, gcc and pkg-config (and many more...)
- A web server like Apache2
Create a directory in the path served by your web server.
Of course, don't forget to run the Emscripten SDK evironment script before doing anything (emsdk/emsdk_env.sh
).
Review the content of the script make.sh
and adapt it to your project or your environment.
Make the script make.sh
executable (chmod +x ./make.sh
).
Feel free to add new functions to imagick.c
and index.html
, and ask for a pull request to make your work available to as many people as possible (MagickWand Image API for C documentation is available here).
And enjoy.
For conversions, we link ImageMagick against libwepb for full webp support, zlib and libpng for full png support, libjpeg for full jpeg support, openjpeg for full jpeg2000 support and libheif to support avif files. Also it is possible to convert formats like PNG, WEBP or JPEG with JS directly, thanks to the native browser support (See below for an explanation).
Fast Fourier transform is now supported.
We use the Emscripten filesystem (FS) to exchange data between JS and ImageMagick.
For the data exchanges between the browser and the magickwand library, we found convenient to use the native raw ".rgba" ImageMagick file format, which has the same byte order as the JS ImageData.
The imagick.html
file present is not very usefull, the most important files are imagick.wasm
, imagick.js
and index.html
.
Since the JS Canvas permits shapes and text drawings natively, we don't see the need to use ImageMagick for this purpose, and we didn't compile IM with the freetype lib.
And yes for many years now we use pure browser JS and jquery, and still do, we are not much exited by the use of Nodejs, or TypeScript... sorry. But feel free to contribute on this part.
Here are the options overview set at compliation time for ImageMagick:
Option Value
------------------------------------------------------------------------------
Shared libraries --enable-shared=no no
Static libraries --enable-static=yes yes
Module support --with-modules=no no
GNU ld --with-gnu-ld=yes yes
Quantum depth --with-quantum-depth=16 16
High Dynamic Range Imagery
--enable-hdri=yes yes
Install documentation: no
Memory allocation library:
JEMalloc --with-jemalloc=no no
TCMalloc --with-tcmalloc=no no
UMem --with-umem=no no
Delegate library configuration:
BZLIB --with-bzlib=no no
Autotrace --with-autotrace=no no
DJVU --with-djvu=no no
DPS --with-dps=no no
FFTW --with-fftw=yes yes
FLIF --with-flif=no no
FlashPIX --with-fpx=no no
FontConfig --with-fontconfig=no no
FreeType --with-freetype=no no
Ghostscript lib --with-gslib=no no
Graphviz --with-gvc=no
HEIC --with-heic=yes yes
JBIG --with-jbig=no no
JPEG v1 --with-jpeg=yes yes
JPEG XL --with-jxl=no no
LCMS --with-lcms=no no
LQR --with-lqr=no no
LTDL --with-ltdl=no no
LZMA --with-lzma=no no
Magick++ --with-magick-plus-plus=no no
OpenEXR --with-openexr=no no
OpenJP2 --with-openjp2=yes yes
PANGO --with-pango=no no
PERL --with-perl=no no
PNG --with-png=yes yes
RAQM --with-raqm=no no
RAW --with-raw=no no
RSVG --with-rsvg=no no
TIFF --with-tiff=no no
WEBP --with-webp=yes yes
WMF --with-wmf=no no
X11 --with-x=no no
XML --with-xml=no no
ZLIB --with-zlib=yes yes
ZSTD --with-zstd=no no
wasm-ld
is warning us about a function in the x265 library :
wasm-ld: warning: function signature mismatch: x265_cpu_xgetbv
>>> defined as (i32) -> i64 in /opt/local/www/apache2/html/imagick/image_magick/lib/libx265.a(cpu.cpp.o)
>>> defined as (i32, i32, i32) -> void in /opt/local/www/apache2/html/imagick/image_magick/lib/libx265.a(primitives.cpp.o)
It doesn't seem to affect anything about the AVIF format, but may affect HEIC, we haven't done any test yet. Let me know if you found something.
Here is an example of convertion to PNG thanks to the canvas.
let img = document.querySelector('#my_image');
let canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
img.src = canvas.toDataURL('image/png');
Thanks to this process, you can convert any PNG, JPEG or even WEBP format to another.
The last line can be replaced with this one for JPEG:
img.src = canvas.toDataURL('image/jpeg', 0.8);
where 0.8
is the image quality (0 to 1).
Or with this one for WEBP (with recent browsers only):
img.src = canvas.toDataURL('image/webp', 0.7);
where 0.7
is the image quality (0 to 1).
See the documentation here to learn more.