gimp でバッチ処理

この話は 分子の座標から GIF animation を作る の続きです。

さらに, 石岡@農研センター様が, このページのグレードアップ版? Script-Fu で 画像形式変換のバッチ処理 を作成されています.

やりたいことは、pbm 形式のグラフgif 形式のグラフに変換するのに gimp のバッチ処理で出来ないものかということで、具体的には
・配色を変える
・大きさを変える
・フォーマットを変える
ということです。

gimp の man を見ますと
     -b, -batch <commands>
               Execute the set of  <commands>  non-interactively.
               The  set of  <commands> is typically in the form of
               a script that can be executed by one of  the  Gimp
               scripting extensions.
ということで、the set of <commands> を用意すれば なんだか出来そうです。ということで、gimp のユーザーマニュアルを 探すと GUM [ja] という日本語のページがあります。 ここにある Script-Fu を参考に作ってみます。 もっとも、日本語訳は全て完了というわけではないので、 英語版の本家はこちら

このマニュアルは丁寧なので、 Script-Fu に書いてあるとおりにサンプルの スクリプトを作っていけば、大体要領が掴めるかと思います。 逆にいうと、ここを読まないと Script-Fu のことはさっぱり判りません。 たとえば、ここのサンプルにある 38.8 コメント付きのスクリプト例を $HOME/.gimp/scripts/uni.scm とコピーして実行してみます。 ただし、
; Finally register our script with script-fu.
(script-fu-register "uni-img"
                    ここをこのように修正↓
                    "<Toolbox>/Xtns/Script-Fu/Tutorials/Uniform image"
                    "Creates a uniform image"
                    "Dov Grobgeld"
                    "Dov Grobgeld"
                    "1997"
                    ""
                    SF-VALUE "size" "100"
                    SF-COLOR "color" '(255 127 0))
と修正しておかないと、Toolbox から、つまり 「拡張」→「Script-Fu」→「Tutorials」→「Uniform image」で 参照することが出来ませんでした。

次に、「38.9 画像メニュー中にスクリプトを」を読んでみたところで、 自分のやりたい仕事にとりかかりました。 script-fu-copy-blur をカット&ペーストして動かして、表示している画像の 処理はこんな感じにするんだということを理解したところで、 実際に自分のやりたい処理
・配色を変える
・大きさを変える
・フォーマットを変える
を実行するスクリプトを書いてみます。 ここで役に立つのが 「Script-Fu Console」と「DB Browser」で、 前者はコマンドを一つ一つ手で実行出来るシェルみたいなもので、 後者では登録されている関数の仕様(入出力の書式など)がわかります。
こういうの、本当に便利で、初心者に親切なアプリケーションって 「まず、対話的に使用できて(別にGUIGUIしている必要は 必ずしもないが)初歩的な使い方はすぐにわかる」 ふうに出来ていて、さらに「そのあとで使い倒すためのツールが整っている」 という設計のものが良いですよね。 たとえば、ruby でも 対話モード(irb)があったりして最初に勉強するのにありがたかったです。
それはともかく、 配色を変えるのは plug-in-exchange で、大きさを変える(crop)は gimp-crop で、色を indexed にするためには gimp-convert-indexed だということが、DB ブラウザで検索するとわかります。

てなことで、$HOME/.gimp/scripts/pbm2gif.scm というファイルを 以下のように作ってみました。
; Define the function of the script and list its parameters
; The parameters will be matched with the parameters listed
; below in script-fu-register.
(define (pbm2gif inFile outFile)
; Load an img
  (set! img (car (gimp-file-load 0 inFile inFile)))
; get drawable
  (set! drawable (car (gimp-image-active-drawable img)))
; crop image
  (gimp-crop img 475 385 78 96)
; exchange colors
  (plug-in-exchange 1 img drawable 0 0 0 218 218 218 0)
  (plug-in-exchange 1 img drawable 255 85 85 255 255 0 0)
  (plug-in-exchange 1 img drawable 85 85 255 255 0 255 0)
  (plug-in-exchange 1 img drawable 85 255 85 0 255 0 0)
  (plug-in-exchange 1 img drawable 255 255 255 0 0 0 0)
; convert to indexed
  (gimp-convert-indexed img 0 6)
; if you want to see the procedure
;  (gimp-display-new img)
;  (gimp-displays-flush)
; save file as gif 
  (file-gif-save 1 img drawable outFile outFile 1 0 0 0)
)
; Register our script with script-fu.
(script-fu-register "pbm2gif"
                    "/Xtns/Script-Fu/Tutorials/pbm2gif"
                    "Converts a pbm file to gif"
                    "Hitoshi Washizu"
                    "Hitoshi Washizu"
                    "1999"
                    ""
		    SF-VALUE "Infile"       "\"hoge.jpg\""
		    SF-VALUE "Outfile"       "\"hoge.gif\""
		    )
変換する色だとか、crop する領域の大きさだとかはスクリプトに埋め込んで "決め打ち"してしまいました。汎用性を求めなければ、まぁいいって感じで。 入力するファイルと出力するファイルだけは指定出来るようにしておきます。 このスクリプトをアニメーションで使う 20 枚の画像に対して実行する わけですから。

対話的に、このスクリプトが動くことを確認するために、 以下の行をコメントをはずしてして動かしてみます。
; if you want to see the procedure
  (gimp-display-new img)
  (gimp-displays-flush)
このファイルを $HOME/.gimp/scripts/pbm2gif.scm として保存して、 gimp を起動すると、このようにスクリプトが登録されます。

で、ここをクリックしてみると

あ、別にこのスクリプトは RGB カラーの画像だったら何でも使えるので "hoge.jpg" になっていますが、ともかく、Infile を @xyz01.pbm にして、Outfile をたとえば @xyz01.gif にすると gif 形式のグラフに なりますね。

余談ですが、上のスクリーンショットの文字はちっこくなっていて 恰好がよろしいですが、これは 永尾さんのナガ10 フォントを使っています。gimp だと何もリソースを変更することなしに このフォントをインストールするだけで表示が変更されました。 わしはデスクトップといっても 800x600 で使っているので、 10ポイントの日本語フォントはちっこくてありがたいです。ということで、 ネットスケープ コミュニケータの表示 なども ナガ10 にしています。

上の「コンソール」から Script-Fu Console を開いて、ここから 実行できることも確認してみますと、

() が帰ってきているということで、うまくいきます(warning が出ますが)。
ということで、再び 以下の行をコメントをつけて保存しておきます。
; if you want to see the procedure
;  (gimp-display-new img)
;  (gimp-displays-flush)
今度は、いよいよバッチ処理をしたいわけですが、 「20枚の指定したファイルについて pbm2gif スクリプトを実行させる」 という、別のスクリプトを作って、これを $HOME/.gimp/scripts/run-all.scm として保存しておきます。
(define (run-all)
  (pbm2gif "@xyz01.pbm" "@xyz01.gif")
  (pbm2gif "@xyz02.pbm" "@xyz02.gif")
  (pbm2gif "@xyz03.pbm" "@xyz03.gif")
  (pbm2gif "@xyz04.pbm" "@xyz04.gif")
  (pbm2gif "@xyz05.pbm" "@xyz05.gif")
  (pbm2gif "@xyz06.pbm" "@xyz06.gif")
  (pbm2gif "@xyz07.pbm" "@xyz07.gif")
  (pbm2gif "@xyz08.pbm" "@xyz08.gif")
  (pbm2gif "@xyz09.pbm" "@xyz09.gif")
  (pbm2gif "@xyz10.pbm" "@xyz10.gif")
  (pbm2gif "@xyz11.pbm" "@xyz11.gif")
  (pbm2gif "@xyz12.pbm" "@xyz12.gif")
  (pbm2gif "@xyz13.pbm" "@xyz13.gif")
  (pbm2gif "@xyz14.pbm" "@xyz14.gif")
  (pbm2gif "@xyz15.pbm" "@xyz15.gif")
  (pbm2gif "@xyz16.pbm" "@xyz16.gif")
  (pbm2gif "@xyz17.pbm" "@xyz17.gif")
  (pbm2gif "@xyz18.pbm" "@xyz18.gif")
  (pbm2gif "@xyz19.pbm" "@xyz19.gif")
  (pbm2gif "@xyz20.pbm" "@xyz20.gif")
)
(script-fu-register "run-all"
                    "/Xtns/Script-Fu/Tutorials/run all"
                    "Converts all xyz files"
                    "Hitoshi Washizu"
                    "Hitoshi Washizu"
                    "1999"
                    ""
		    )
でもって、この run-all というスクリプトを シェル(コマンドライン,tcsh)から呼び出すことが出来れば成功です。
% gimp -n -b '(run-all 1)' '(gimp-quit 0)'
この書き方は GUM 本家の情報 を参考にしました。
メモリが足りないとスワップが起きますが、ともかく、 gimp を使いながら、あの華麗な gtk の窓を一切開くことなしに バッチ処理できました。ということで、この作業は最終的には X Window を起動することなしに実行することが出来ます。