Easy to setup and use, ImageMagick Node.js and Browser API and Command Line Interface.
run(): command script/template syntax
convert command).npm install and you are ready to go.See magick-wasm
npm install magica
If you only will use the Command Line Interface perhaps a better option is installing it globally:
npm install -g magica
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
--input can be a glob of files, useful for batch multiple images or to build gifs from several images. --command use single quotes '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.
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))
})()
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
})()
dist/src/imageMagick/compiled/magick.wasm is located at the same folder of your .js bundle file.test-browser/ filenpm run test-browserIf 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="https://github.com/cancerberoSgx/magica/raw/desktop-client-0.0.1/other/location/magica.js"></script>
Script src attribute with a parameter
<script src="https://github.com/cancerberoSgx/magica/raw/desktop-client-0.0.1/other/location/magica.js?MAGICA_WASM_LOCATION=https://my.cdn.com/something/magick.wasm"></script>
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 syntaxWhile 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
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
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.
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
TODO: update with run() and script()
Options are the same for the command line and the API:
--input: string[]: (command line only) Input file paths. It can also be glob patterns. For passing more than one use --input multiple times. It's important that the base name of these paths match the file names given in the command.--command: string | string[]: An ImageMagick command, for example: "convert foo.png -scale 50% bar.gif".--inputFiles?: string | string[]: (API only) The list of input files referenced in given command. It's important that the name of this files match the file names given in the command. If string and a file exists (node.js) then that file will be used. Otherwise it will be considered a url. In later cases, the filename will be the base name of file or url.--localNodeFsRoot?: string:--emscriptenNodeFsRoot?: string:--help?: boolean: (command line only)--debug?: boolean:disableNodeFs?: boolean: (node.js only) Don't use system's filesystem in Node.js but memory filesystem (just like in the browser). This could be faster if read/write many images but consumes more memory.src/imageMagick/compiled/ can be generated from that project executing npm run test-node.convert, ìdentify, mogrify, etc. (Notice that is not the C/C++ API like MagickCore, MagickWand, etc, but the Command line interface of utilities like convert which IMO covers 99% of use cases and is easy to use (compared to the C/C++ APIs).See TODO.md.
$ claude mcp add magica \
-- python -m otcore.mcp_server <graph>