ページ

2014-10-12

PythonでGIMPのスクリプトを書く(Python-Fuの書き方)

これはGIMPでスクリプトを使おう!と思ったものの久々のScheme (Script-Fu)にめげて「GIMPってPythonも普通に使えるんじゃね?」ってことで試してみたら罠もあったけどいい感じだったよって記事である。Linuxではもちろん、Windowsでもインストーラから入れればPythonが同梱されているので、気軽に使える。

もちろんGIMPを普段から使うのであれば、マクロ的に使ってもいいと思うのだけど、GIMPを使ってなくても「UIの必要な画像処理」には便利だと思う。画像の表示、範囲選択とか、そういうのが本筋じゃないプログラムにさらっと提供できる。たとえば、自前のOpenCVを使った画像処理ライブラリのフロントエンドとかね。

枝葉の処理が多いのでこのスクリプト自体は解説しないが、自分が作ろうと思って作ったもの(後述)はこちら


PythonでのGIMPのスクリプトの書き方

基本的には、developerworksの記事「Python を使用して GIMP 用のプラグインを作成する」がわかりやすいので、詳しいチュートリアル的なものが必要であればそちらのほうで。こちらは、だいたいどんなことをすればできあがるのかなというのをイメージできるようざっくりと書くことにする。

1. 雛形を持ってきて配置

雛形があれば余計なところに時間がかからないので、作ったのがこちら。


これを、~/.gimp-2.8/plug-ins (WindowsであればC:\Users\{username}\.gimp-2.8\plug-ins)に適切なファイル名をつけて配置する。なお、Unix系では実行権が必要なのでつけておく。
$ chmod a+x helloworld.py

2. register関数を書く

まずプラグインをGIMP側に登録するregister関数の引数を埋めていく。
詳しくは先のdeveloperworksの記事、あるいはGIMP Python Documentationを参照のこと。

基本的には見ての通りのところを直していけばいいのだが、引数と書いた部分の配列に、項目を設定しておくと、スクリプト起動時にダイアログが現れて選択させることができる。例えば、文字列を受け取りたければ、以下のタプルを配列に入れる。
(PF_STRING, "string", "説明", 'デフォルト値')
PF_STRINGのような型にどんなものがあるかは、やはりGIMP Python DocumentationのPlugin Frameworkを参照。

ここに入れた項目は、設定した関数名の関数に渡るので、入れた項目を覚えておく。

実体の関数(雛形のplugin_main)を書く

plugin_mainとregister関数で指定してあるので、この関数に処理を実装していく。

引数は、現在のイメージ、レイヤーに続いて、先ほどregister関数で指定した引数を受け取るようにする。

中の実装に関しては、大きく分けて以下の2つの方法で関数を呼び出していく形になる。

A. pdb.~で、プロシージャデータベースの関数を呼び出す

GIMP内部にプラグインの処理を登録しておくプロシージャデータベース(Procedual Database, pdb)というものが存在し、この関数をpdb.なんとかのような形で呼び出すことができる。

例えば、このような形である。
pdb.gimp_image_scale(img, 640, 480)

どのようなプロシージャが存在するかは「ヘルプ>プロシージャーブラウザー」よりプロシージャーブラウザーを起動して検索することができる。


B. gimpモジュールに含まれる関数を呼び出す

レイヤーを作成したりといったベーシックな処理であれば、gimpモジュールにも関数が準備されている。

例えば、以下のようにするとメッセージを表示することができる。
gimp.message("Hello, World")

実装されている関数についてはGIMP Python Documentationの「GIMP Module Procedures」に一覧がある。


あるいは、フィルター>Python-Fu>コンソールで、Python Consoleが動くので「help(gimp.Image)」などとしても良い。

Pythonで文法チェック

書き終わったら、そのスクリプトをpythonコマンド(Windowsではインストールパス\Python\pythonにある)で実行してみる。実行したとき、gimpfuモジュールがない旨のメッセージが出ればひとまずOK。これで文法的なミスがないか確認する。

>"C:\Program Files\GIMP 2\Python\python" C:\Users\yoichi\.gimp-2.8\plug-ins\helloworld.py
Traceback (most recent call last):
  File "C:\Users\yoichi\.gimp-2.8\plug-ins\helloworld.py", line 5, in 
    from gimpfu import *
ImportError: No module named gimpfu

起動

ここでGIMPを起動し、メニュー項目に指定した項目があり、実行できれば成功である。

丁寧にチュートリアル通り作ればいいが、動けばいいやと雰囲気で適当に作ったらはまった。

(Unixでは)実行権を与える必要がある

忘れがちであるが、Unix系ではplug-insに置いたスクリプトに実行権が必要である。

main()を忘れない

register()のあとにmain()があるが、これがないと動作しない。詳しくは追いかけていないが、実行権が必要であるところからして、このスクリプトは単体のプロセスとして動作し、main()の中でGIMP本体と通信して動作しているのだと思う。

image, layer引数が必要

引数の配列で宣言した項目のほかに、現在のイメージとレイヤーを受け取っておく必要がある。

Windowsではデバッグしにくい

Unixではコンソールからgimpコマンドで起動すればエラーが出てくるが、Windowsではコンソールはデフォルトではない。そのため、困っているときは以下のように起動してみる。
gimp --console-messages 

また、関数部分のみ実行されるようにしてPythonコンソールからimportして呼び出してみたり、sys.stderrをopen("file/path", "a")で差し替えてみたりといったデバッグテクニックがあるので、GIMP Forumの「Debugging python-fu scripts 」の記事を参照されたい。

Windows版GIMPではメッセージボックスが出ない(ことがある?)

どっかの変数のデフォルト値の違いだと思うが、デフォルトではWindowsでインストールしたGIMPではgimp.messageでメッセージボックスが出なかった。
そういうときは、ウィンドウ>ドッキング可能なダイアログ>エラーコンソールで、リスト形式でエラーメッセージを見ると良い。

参考

今までのリンクの他にも「Writing Python script for Gimp 」のブログ記事もわかりやすい。

こちらの「Beginning GIMP: From Novice to Professional」にあるいくつかのサンプルスクリプトを読むともっとイメージがつきやすいと思う。

また、GIMP Plugin Registryの「python」タグでもPythonでの記述についてのサンプルが得られる。

何に使ったか?

ということで無事に書けるようになったわけだが、そもそもなぜ書くことになったか?

先日、画像のピクセル数が見た目サイズの2倍の画像をベタなHTML+CSSに入れ込んでいくという作業があり、物理電卓をバチバチ叩きながら1/2サイズを作っていった。

「これは機械にやらせたほうがいい」と思って「画像... 自動化... UI作るの面倒... ここはGIMPじゃね?」ということで久々にScript-Fuを書こうとしたところ、どうもScheme脳に頭が切り替わらない。「Pythonも使えるんじゃね?Windowsも普通に入ってるわ」ということでPythonでGimpマクロ的なものを書いてみた次第である。

結果、SchemeによるScript-Fuに比べると素直じゃない感はあるものの、仕組みを掴んでしまえば、Lispを普段書かない自分には圧倒的にサクサク書くことができた。そのギャップから、普段Pythonは書けないのに「俺ひょっとしてPython書けるんじゃね?」という謎の錯覚が生まれた。

なお補足しておくと、どっちかっていうと今回は「これは覚えるチャンス」的な意味が大きくて、このケースでは実際にはCompassにサイズ計算させるとか、とか、sh+ImageMagickやPowerShellでディレクトリに置いたやつを一気に作る、とかのほうが現実的なアプローチだとは思うので、そちらを検討されたほうがよろしいかと。

0 件のコメント:

コメントを投稿