node.jsのgmライブラリでCopyOpacityするのに1日ハマった話するわ
gmライブラリ
node.jsにおける画像編集の鉄板?ライブラリである。 バックでGraphicsMagick(ImageMagick)が動いており、 それらをnode.jsの機能のように使うことをapiなのだろうか。 今回はこのgmライブラリを使ってはまりまくったので、 後に筆者のような愚かな人間が生まれないように記事を書く。 多少心が荒んでいるので、丁寧語が抜けていることをお許し願いたい。
今回やりたかったこと
サムネイルを作る目的ではないが、 こちらの記事にあるようにmaskとなるpngファイルから 透過値をコピーして、丸く切り取るようなことがしたかった。 また、作業に際し速度が必要であったため、 ImageMagickではなくGraphicsMagickを使うことにした。
compositeとconvert
おそらく、ちゃんとした区分があるのだろうが、筆者のなんとなくの理解では
- 画像の変換系はconvert
- 画像の合成系はcomposite
である。
GraphicsMagickにある、コマンドはそんなに多くない。
というかむしろほとんどのことは convert
ですませるのだろう。
convert
を使う場合、基本的に画像ファイルの引数は二つだ。
ここで、問題が生じる。
maskを用いた透過値のコピーには引数が3つ必要なのである。
上記ページからもわかる通り、このような場合はcomposite
を用いる他ない。
gmライブラリの仕様上注意
今回のメインディッシュである。
gmライブラリは今のところ、convert
コマンドしかサポートしていないのだ。
これが何を意味するかというと,
gmライブラリで今回の目的が達成できない
最終的な筆者のソリューションは、おそらくみなさんが行なっているであろう。
child_process
を使って、シェルに直接実行してもらう方針である。
// gmモジュールがcompositeをサポートしていないため関数定義
internals.gmcomposite = function(maskImagePath, tempImagePath, newImagePath, callback) {
var gmspawn = spawn('gm', ['composite', '-quality', 100, '-compose', 'CopyOpacity', maskImagePath, tempImagePath, newImagePath]);
gmspawn.stdout.on('data', function(data) {
console.log('stdout: ' + data);
})
gmspawn.stderr.on('data', function(data) {
console.log('stderr: ' + data);
})
gmspawn.on('exit', function(code) {
if (code !== 0) {
callback(code, null)
}else {
callback(null, null)
}
})
};
これでひとまずは実行できた。 恥ずかしい話、ここにたどり着くまでに1日の時間を要した。
GraphicsMagickのややこしいオプション
今回、ここまで時間がかかったのにはgmがサポートしていなかったことと 合い重なってGraphicsMagickのオプションがわかりづらいと言うことがある なんと、
convert
コマンドには-composite
composite
コマンドには-convert
オプションが存在するのだ。
筆者は永遠とgmライブラリの-composite
オプションを使い、
どのオペレータを用いればmaskを用いたCopyOpacityができるのか延々と悩んでいたわけである。
まとめ
え、今回の問題に直面した時の反省点ですか?…マジでわからん。。。 こう言う泥沼にハマった時の対処法誰か教えてください。。