Web assembly ImageMagick
This project is not affiliated with ImageMagick , but is merely recompiling the code to be WebAssembly. I did this because I want to bring the power of ImageMagick to the browser.
Table of Contents
Demos and examples
Status
Image formats supported
Supports PNG, TIFF, JPEG, BMP, GIF, PhotoShop, GIMP, and more!
See a list of known supported formats in this demo
Features not supported
API
Reference API Documentation
Reference API Documentation
High level API and utilities
wasm-imagemagick
comes with some easy to use APIs for creating image files from urls, executing multiple commands reusing output images and nicer command syntax, and utilities to handle files, html images, input elements, image comparison, metadata extraction, etc. Refer to API Reference Documentation for details.
import { buildInputFile, execute, loadImageElement } from 'wasm-imagemagick'
const { outputFiles, exitCode} = await execute({
inputFiles: [await buildInputFile('http://some-cdn.com/foo/fn.png', 'image1.png')],
commands: [
'convert image1.png -rotate 70 image2.gif',
'convert image2.gif -scale 23% image3.jpg',
],
})
if(exitCode !== 0)
await loadImageElement(outputFiles[0], document.getElementById('outputImage'))
Accessing stdout, stderr, exitCode
This other example executes identify
command to extract information about an image. As you can see, we access stdout
from the execution result and check for errors using exitCode
and stderr
:
import { buildInputFile, execute } from 'wasm-imagemagick'
const { stdout, stderr, exitCode } = await execute({
inputFiles: [await buildInputFile('foo.gif')],
commands: `identify foo.gif`
})
if(exitCode === 0)
console.log('foo.gif identify output: ' + stdout.join('\n'))
else
console.error('foo.gif identify command failed: ' + stderr.join('\n'))
low-level example
As demonstration purposes, the following example doesn't use any helper provided by the library, only the low level call()
function which only accept one command, in array syntax only:
import { call } from 'wasm-imagemagick'
const fetchedSourceImage = await fetch("assets/rotate.png")
const content = new Uint8Array(await fetchedSourceImage.arrayBuffer());
const image = { name: 'srcFile.png', content }
const command = ["convert", "srcFile.png", '-rotate', '90', '-resize', '200%', 'out.png']
const result = await call([image], command)
if(result.exitCode !== 0)
return alert('There was an error: ' + result.stderr.join('\n'))
const outputImage = result.processedFiles[0]
const outputImage = document.getElementById('outputImage')
outputImage.src = URL.createObjectURL(outputImage.blob)
outputImage.alt = outputImage.name
Importing the library in your project
With npm
npm install --save wasm-imagemagick
**IMPORTANT:
Don't forget to copy magick.wasm
and magick.js
files to the folder where your index.html
is being served:
cp node_modules/wasm-imagemagick/dist/magick.wasm .
cp node_modules/wasm-imagemagick/dist/magick.js .
Then you are ready to import the library in your project like this:
import { execute} from 'wasm-imagemagick'
or like this if you are not using standard modules:
const execute = require('wasm-imagemagick').execute
Loading directly from html file
If you are not working in a npm development environment you can still load the library bundle .js file. It supports being imported as JavaScript standard module or as a UMD module.
Importing magickApi.js as a JavaScript standard module:
Basic version, just reference online https://knicknic.github.io/wasm-imagemagick/magickApi.js no files needed at all.
See samples/rotate#code.
Relevant portions called out below "..."
means code is missing from example
<script type='module'>
import * as Magick from 'https://knicknic.github.io/wasm-imagemagick/magickApi.js';
let DoMagickCall = async function () {
let processedFiles = await Magick.Call([{ 'name': 'srcFile.png', 'content': sourceBytes }], ["convert", "srcFile.png", "-rotate", "90", "-resize", "200%", "out.png"]);
};
DoMagickCall();
</script>
Working example source code.
Below examples need additional files coppied:
Copy magick.js
, magick.wasm
in the same folder as your html file.:
Importing a bundle as a JavaScript standard module:
<script type="module">
import { execute, loadImageElement, buildInputFile } from '../../dist/bundles/wasm-imagemagick.esm-es2018.js'
</script>
Working example source code
Using the UMD bundle in AMD projects (requirejs)
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
<script src="../../dist/bundles/wasm-imagemagick.umd-es5.js"></script>
<script>
require(['wasm-imagemagick'], function (WasmImagemagick) {
const { execute, loadImageElement, buildInputFile } = WasmImagemagick
Working example source code
Using the UMD bundle without libraries
<script src="../../dist/bundles/wasm-imagemagick.umd-es5.js"></script>
<script>
const { execute, loadImageElement, buildInputFile } = window['wasm-imagemagick']
Working example source code
Build instructions
git clone --recurse-submodules https://github.com/KnicKnic/WASM-ImageMagick.git
cd WASM-ImageMagick
sudo snap install --edge node --classic
sudo npm install typescript -g
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
npm install
Produces magick.js
, magickApi.js
, & magick.wasm
in the current folder.
Run tests
npm test
will run all the tests.
npm run test-browser
will run spec in a headless chrome browser. These tests are located at ./spec/
.
npm run test-browser-server
will serve the test so you can debug them with a browser.
npm run test-browser-start
will run the server and start watching for file changes, recompile and restart the server for agile development.
npm test-node
will run some tests with nodejs located at ./tests/rotate
.