Image Processing in Browser
- 2 minutes read - 341 words
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