Home

Awesome

Build Status Coverage Status Github Actions Workflow

Magica

Easy to setup and use, ImageMagick Node.js and Browser API and Command Line Interface.

Contents

<!-- toc --> <!-- tocstop -->

Playground & demos

Summary

Status

WebAssembly build

See magick-wasm

Install

npm install magica

If you only will use the Command Line Interface perhaps a better option is installing it globally:

npm install -g magica

Command line

The command line interface will let you use the same Image Magick commands. The only difference is that you will need to explicitly list the input files paths.

In the following example we execute identify n.png:

$ magica --command "convert foo.tiff -scale 30% -rotate 33 output/img/bar.png" --input ../img/foo.tiff
$ magica --command "identify bar.png" --input output/img/bar.png 
bar.png PNG 109x145 109x145+0+0 8-bit sRGB 39796B 0.000u 0:00.000

Notice that besides passing the ImageMagick command with --command we also passed the image files using --input. It is important that the basename of given input files match the file names referenced in the command (n.png):

Some other examples:

magica --input "frames_*.jpg" --command "convert 'frames_[0-9].gif' -scale 44% tmp.gif"

TODO: verify that works

JavaScript API

The JavaScript API is equivalent to the Command Line Interface. The command references files that are passed separately. Since this library supports both Node.js and the browser, users are responsible of providing the input file contents.

Node.js

In the following example we convert an image in Node.js. (Checkout run() for a flexible script-like syntax below)

import {main} from 'magica'
import { readFileSync, writeFileSync } from 'fs'
(async ()=>{
 const result = await main({
    debug: true,
    command: 'convert foo.png -scale 50% foo2.png',
    inputFiles: [ 'test/assets/n.png' ]
  })
  result.outputFiles.forEach(f => writeFileSync(f.name, f.content))
})()

Browser

The following example is analog to the previous one but in the browser:

import {main} from 'magica'
(async ()=>{
 const result = await main({
    debug: true,
    command: 'convert bar.gif -scale 150% -rotate 45 foo.png',
    inputFiles: [ 'static/img/bar.gif' ]
  })
  const dataUrl = `data:image/png;base64,${btoa(String.fromCharCode(...result.outputFiles[0].content))}`
  document.getElementById('img-foo').src = dataUrl
})()

Browser setup

WASM file in different location

If you need to load magick.wasm from a different location than your index.html and even from magick.js it can be done by declaring a global variable with its url or adding a parameter in magica.js script src attribute:

Global variable:

<script>
  MAGICA_WASM_LOCATION = 'https://my.cdn.com/something/magick.wasm'
</script>
<script src="other/location/magica.js"></script>

Script src attribute with a parameter

<script src="other/location/magica.js?MAGICA_WASM_LOCATION=https://my.cdn.com/something/magick.wasm"></script>

Web Worker

Of course in the browser you will want to use a web-worker to process images. Just pass the command object as a message, execute main() in the worker and return back the result.

Both the command and result objects are designed to transfer data between main thread and worker optimally.

See test-browser/webWorker and npm run test-worker script for a working simple example.

run(): command script/template syntax

While ImageMagick provides a syntax to run complex commands performing several operations, main() will be enough most of the time.

Nevertheless magica also supports run() which accept allows to create scripts to execute several commands, just like bash scripts

It supports comments, command splitting in mutiple lines by ending them with \, just like bash scripts:

TODO: show one command divided with \\ and with comments

Commands Sequence

The most useful feature of run() is that it will run the commands serially, and each command output files will be available to next commands as input files automatically:

TODO: example of multiple commands consuming output files

JavaScript templates

TODO: document templates <%= %> in run scripts. the syntax, available context properties and template helpers, how to add new context properties and how to add new template helpers.

Commands pre processors

run() supports adding custom commands preprocessor to support new syntax in scripts. JavaScript templates is a builtin concrete command preprocessor. TODO: example link to the API for registering a new prepro

Options

TODO: update with run() and script()

Options are the same for the command line and the API:

Reference API

Why?

TODO / Road map

See TODO.md.