#概要
ImageMagickを使って画像生成をしようと思っていて、簡単な処理ならターミナル等でコマンドを打って実行するのだが複数の画像を順番に合成するなどシーケンシャルな処理をする場合にそれだとしんどいので何かスクリプトを使いたいなと思って検討した結果JavaScript(以下JS)にしようと思い検討理由と実行記録を残しておきました。
#なぜJSにしたのか
本当に簡単な処理ならShellscriptでもいいかなと思いますが今回はif文もいくつかケースがわかれたりJSONの読み込み等が発生するため除外。もちろんShellscriptでもできますが不慣れだし大抵の人にとっては見にくいケースもあるので。
次にPythonを検討した。PythonMagickなどのライブラリが用意されていて使いやすいということもあるし最近は画像処理で多く使われていたり人気の言語だったりするので。
迷った結果最終的にはElectronでGUI作る必要があるかもしれないというのがあったのでJSにしました。
#実行環境
- macOS Mojave 10.14.6
- node v12.16.1
- シェルは bin/bash
#方法
上記で実行環境書いてますがやり方としてはnode.jsを使ってコマンドラインでJSを呼び出し、JS内でシェルコマンドを実行するものとなっています。JSにもnode-imagemagickなどの直接ImageMagickを使うライブラリがあるのですがライブラリ自体のバグがあった場合に追うのが面倒だなと思ったのと情報量は直接コマンド実行したものの方が多いだろうと思ったため今回はJS内から直接コマンドを実行するようにしています。
node.jsはその時の最新の安定板を使いました。nodeの最新版の入れ方は参考にある記事等を見ていただければと思います。
JSからシェルコマンドを実行する方法としてはexec
とexecSync
というものがあって前者は非同期実行で後者は同期実行です。今回の例ではexecSync
を使います。
以下がプログラム。1行目でexecSyncを読み込み2行目でexecSyncを用いてImageMagickのコマンドを実行。
ちなみに今回のImageMagickのコマンドはconvertを用いて100x100の赤い画像を生成しています。
const {execSync} = require('child_process');
execSync('convert -size 100x100 xc:red red.jpg');
変数を用いて画像の大きさを変更したといった場合もあるのでその場合はutil.formatを使います。
以下は先ほどと同様に100x100の赤い画像を作成した後に青文字で"hoge"という文字を描いています。
また、util.formatを用いてフォントサイズや色や文字の内容を変数で渡すようにしています。
const {execSync} = require('child_process');
const util = require('util');
const fontSize = 24;
const color = 'blue';
const content = 'hoge';
execSync('convert -size 100x100 xc:red red.jpg');
execSync(util.format(
'convert -font Bookman-DemiItalic -gravity center -pointsize %d -fill %s -draw "text 0,0 %s" red.jpg red.jpg',
fontSize, color, content));
上記のようにutil.formatを使ってコマンドをプログラムによって柔軟に変更することができるので組み合わせることで複雑な画像も生成できるかと思います。
画像を使う業務をしている方は使いこなすと思わぬところで業務効率もあがると思うのでで色々試してみましょう!