Image Processing in Browser
ImageMagick
One of the oldest, free and opensource tool to manipulate images. This cross platform library can now work natively in the browser thanks to web assembly github.com/KnicKnic/WASM-ImageMagick. In this post I’ll explore the library and show how easy it is to actually incorporate in a ReactJS application
npm installation
Post installation it is necessary to copy the magick.wasm
and magick.js
to static/js
location.
npm install --save wasm-imagemagick
cp node_modules/wasm-imagemagick/dist/magick.wasm public/static/js
cp node_modules/wasm-imagemagick/dist/magick.js public/static/js
API
import { call } from "wasm-imagemagick";
The most low level way to deal with imagemagick wasm is the call
API. It takes an array of images and a sequence of arguments to perform the operation on image(s) just like the command line utility.
JavaScript File
File
type object in JavaScript represents a blob which is obtained mostly from the <input>
element’s filelist. It can be created manually as well to represent any supported file type and fill the data with arbitrary bytes.
var file = new File(["\0"], "file.png", { type: "image/png" });
file.arrayBuffer().then((v) => console.log(new Uint8Array(v)));
// Output: [0]
While working with ImageMagick you’ll need a file object either obtained from user upload or fetching it from a remote location.
Executing Command
With the call
API it’s almost similar to running ImageMagick on CLI. For example if you want to run the command.
magick convert input.png -rotate 90 -resize 200% out.png
first prepare the input image
// imageFile instanceof File -> true
const content = new Uint8Array(await imageFile.arrayBuffer());
const image = { name: "input.png", content };
Then write out the command as a sequence of arguments in an array.
const command = [
"convert",
"input.png",
"-rotate",
"90",
"-resize",
"200%",
"out.png",
];
and execute the API. It will return a result object with an array of processed image files.
const result = await call([image], command);
const url = URL.createObjectURL(
new Blob([result.outputFiles[0].buffer], { type: "image/png" })
);
The extracted URL can be assigned to an <img>
element to display the output image in the browser.
Example
The sample implementation with a bit more options can be found here