GIMPでバッチ処理をさせる
(この記事はGIMP 2.6.11の時に書きました。)
自炊でスキャンした画像ファイルに一括で処理したいということでいろいろ調べて実験した時のメモ。
Photoshop(Elementsではない)ならアクションを記録して簡単に出来るらしいが、バッチ処理程度で買うには高いのでGIMPで処理することに。
ただGIMPには処理をGUIで簡単に操作を記録できるわけではなく、スクリプトを組む必要がある。
Linuxとかだと標準でいろいろな言語で作れるらしいが、Windowsだと基本的に何も入れていない状態だとScript-Fuだけみたい。
今回は複数のPCで面倒なく動かしたいのでScript-Fuで作ることにしたのだが結構落とし穴にはまってしまった。
自分がはまった落とし穴
- 文字コードと改行コード
- 改行コードはLEまたはCRLE 文字コードはUTF-8N
- 文字コードをUTF-8にしていたら訳の分からないエラーばかり出ます。
- Shift-JISやEUCでも動作しますがGUI上では文字化けします。
- コマンドラインで渡すときには「\」や「"」をエスケープして渡す必要がある
- コマンドラインの引数の一つとして渡すため
- 引数のサイズに注意
- 開放は忘れずに(gimp-image-delete image)
- これをやらずに同時にパラメータを渡すとメモリリークが恐ろしいことになります。
実装方法
GIMPでの起動コマンドラインの説明
http://docs.gimp.org/2.6/ja/gimp-fire-up.html#gimp-concepts-running-command-line
Script-Fuは適当に調べてください。 プログラミングを少しやったことがある人なら簡単です。
例として、パブリックのサンプルピクチャから C:\\out\\Koala.bmpに出力するとすると
フィルタ([GIMP実行ファイルのあるディレクトリ]/App\gimp\share\gimp\2.0\scriptsに適当なファイル名で保存されているとする)
(define ([フィルタ名] inPath outPath)
(let*
(
(Image (car (gimp-file-load RUN-NONINTERACTIVE inPath inPath)))
(layer (car (gimp-image-get-active-layer Image)))
)
[ここで画像に処理を加える]
(file-bmp-save 1 Image layer outPath outPath)
)
)
[GIMPの実行ファイル] -i -f -b "([フィルタ名] \"C:\\Users\\Public\\Pictures\\Sample Pictures\\Koala.jpg\" \"C:\\out\\Koala.bmp\")" -b "(gimp-quit 0)"
でこのコマンドを実行して処理が終了しても、自動的にはウィンドウは閉じられず何かキーを押す必要があります。
普通は最初の-b部分を処理する画像の分だけ繰り返しすればいいです。
関数の使い方はメニューのヘルプ下の「プロージャーマネージャー」、使用したいフィルタ・機能の関数名の探し方は「プラグインマネジャー」またはメニュー上においてF1で目的の機能のヘルプを出した後そのサイトのURLを見ると分かるかと思います。
テクニック的な物
マルチスレッド未対応なフィルタばかりなので、バッチ処理で大量に処理させていてもマルチコアCPUの場合使い切ってくれないことが多い。
だからと言って同時実行しようとしてもGIMPPortableの場合、「GIMPPortable.exe」 に複数コマンドを渡しても時折同時実行不可として弾かれてしまう。
その場合、GIMP2.8の時は"(GIMPPortableがインストールされているフォルダ)\App\gimp\bin\gimp-2.8.exe"にコマンドを渡すと弾かれずに実行できる。