省型旧形国電の残影を求めて

戦前型旧形国電および鉄道と変褪色フィルム写真を中心とした写真補正編集の話題を扱います。他のサイトでは得られない、筆者独自開発の写真補正ツールや補正技法についても情報提供しています。写真補正技法への質問はコメント欄へどうぞ

GIMP / Python Tips: 現在アクティブなimageやdrawableを取得する

 GIMPPython-fuで、現在アクティブなimageオブジェクト (GIMPにおけるimageとは、ほぼ画像ファイルのことを指す) をどうやって取得したらよいでしょうか? つまり、複数のimage つまり画像ファイルが読み込まれている状態で、現在アクティブなimageオブジェクトをどのように指定したらよいでしょうか。実は、GIMPには現在アクティブなimageオブジェクトを取得するAPIがありません。

 GIMPAPIgimp.image_list() というものがあります。これは現在GIMPに読み込まれているimageのリストを取得するAPIですが、例えば

image = gimp.image_list() [0]

とやってimageに現在アクティブなimageオブジェクトが読み込まれるかというと、ノーです。gimp.image_list() [0]とやると、最後に開いたimageが取得されます。また、gimp.image_list() [1]だと、最後から2番目に開いたimageオブジェクトが取得できます。最後に開いたimageがアクティブなimageオブジェクトである可能性は高いですが、必ずしもそうではありません。かといって get_active_image というようなAPIは見当たりません。

 ネットで調べてみると以下のようなQ&Aがありました。

www.gimpusers.com このQ & Aを見る限りは、GIMPに現在アクティブなimageオブジェクトを取得するAPIはなく、単に、

def my_plugin_function (image, drawable):

 と書けば、変数 imagedrawableに現在アクティブなimageオブジェクトやdrawableオブジェクトが取得できるというのですが、その通りやってみてもうまく動きません。いろいろ探した結果、以前見ていた日本語のサイトに正解が書かれていました。

lendl.sakura.ne.jp

 単に、プラグインの引数に

def my_plugin_function (image):

と、imageオブジェクトを入れる変数を指定するだけではだめで、register関数の、プラグインの入力ダイアログを指定する部分で、引数に使う変数について以下のように併せて指定する必要があるようです。

[
(PF_IMAGE, "image", "Input image", None),
],

 こうすると変数imageに現在アクティブなimageオブジェクトが取得され、プラグインに渡されるようです。なお、緑の斜体で表現している変数名は変えることができますが、プラグインの引数と、register関数に書かれる変数名は対応していなければなりません。

 これを入れることで、特にダイアログが開くことなく、現在アクティブなimageが取得できました。ただ敢えてダイアログを開きたい場合はどうやるのかが良く分かっていません。Noneの代わりに何かを入れる必要があるとは思いますが...

 なお、現在アクティブな drawableオブジェクトも同様な方法で取得することもできます(引数に、drawableを指定した上で、Register関数で (PF_DRAWABLE, "drawable", "Input drawable", None), を指定)。しかし、imageオブジェクトに関しては現在アクティブなimageを取得するAPIはありませんが、drawableオブジェクトに関しては、アクティブなdrawableを取得するAPIがあります。

  pdb.gimp_image_get_active_drawable(image)

  pdb.gimp_image_get_active_layer(image)

  pdb.gimp-_mage_get_active_channel(image)

といったAPIがそれです。

 ですので、アクティブなオブジェクトを取得するために上記のことを配慮すべきなのはimageオブジェクトのみと考えてよいでしょう。プログラムの可読性という点でも、APIが用意されているなら、なるべくそれを使ってプログラムを書いた方が良いと思います。

 因みに、上述のQ&A(2012年)の通りにやってうまくいかなかった件ですが、おそらくRegister関数の形式の微妙な変更とかかわっているのではないかと推測します。たぶんGIMP2.8導入(2012年4月)の際に若干Register関数の形が変わったようです。Q&Aはそれ以前のバージョンを前提としていると思います。旧来の形のRegister関数を持ったプラグインでも現行バージョンでは動きますが、Register関数が新しい形式だと、旧来の前提が崩れるのだと思われます。私は新しいRegister関数の形式を踏まえて書いていましたので、おそらくそのためうまく走らなかったのだと思います。

 例えば以前下記の記事で紹介したGIMPプラグインは、上述のQ&A通りの方法でアクティブなimageおよびdrawableオブジェクトを取得していますが、register関数の形がちょっと古い形になっています。

yasuo-ssi.hatenablog.com

 先日、自作のGIMPプラグインをいくつかアップデートしましたが、これは、自分が image = gimp.image_list() [0] でアクティブなimageオブジェクトが取得できるものと誤解していたのを、訂正したためです。

 

yasuo-ssi.hatenablog.com

 因みに、GIMP3.0ではこの辺りどうなるかですが、現在開発中のGIMP2.99ではRegister関数がなくなっているようで、Register関数で指定したことを指定しようとすると非常に面倒くさくなっています*1。おそらくまだPython-fuにおけるRegister関数の仕様が固まっておらず実装されていないためだと思われますが...

*1:以下の記事をご覧ください

yasuo-ssi.hatenablog.com