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

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

GIMP2.10 / Python プログラミング Tips: Windowsでプログラムのデバッグを行う

 すでに他の方が指摘されていますが、GIMPPython プラグインの開発を行う際はWindows上だとやりにくいです。というのは、print文などを入れて途中経過を出力しようとしても表示されませんし、Pythonインタープリタのエラーメッセージも表示されません。このため、ImageJに比べて、長いプログラムが非常に書きにくいです。

 その中で、なるべく効率的にデバッグを行うには、次の方法があります。

1. GIMPを verbose モードで起動する

 GIMPを起動するときに、

gimp-2.10.exe --verbose

コマンドラインからオプションをつけて起動すると、起動、終了時のログをウィンドウに表示します。Pythonプラグインが間違っていると、一切メニューに現れないことがありますが、この時読み取りに失敗しているかどうかが確認できます。

 但し、このログウィンドウはプラグインの読み込み認識に失敗しているかどうかの情報しか出てきません。認識には成功しても、その他のコードが間違っている場合は一切情報が出てきません。

2. print文の代わりに、gimp.messageを使う

 Python-fuコンソールで、一文一文コマンドを入れる場合は print文が有効です。しかしプラグインの形で読み込ませたときは print 出力は windows環境では一切表示されません。その代わりに gimp.message文を使います。

gimp.messageを使うときは、まず以下の文で、出力先にエラーコンソールを指定します。

    pdb.gimp_message_get_handler(ERROR_CONSOLE)

その後、gimp.messageを使って途中で値を調べたい変数などを指定すると、その内容をエラーコンソールに表示します。例えば

    gimp.message("image:")
    gimp.message(str(img))

といった具合です。

gimp.messageが取れる引数は、単一の文字列変数もしくは定数ですので、数字その他を表示させるときは文字列に型変換を行う必要があります。

 Pythonインタープリタのエラーメッセージが表示されないので、gimp.messageをプログラムの中の随所に、例えば

gimp.message("1")
gimp.message("2")
gimp.message("3")

というように潜ませて置き、どこまで進んだのか、どのあたりでエラーが発生したのかをあたりをつけることになります。

 

 なお、GIMPを起動するときに、

 "C:\Program Files\GIMP 2\bin\gimp-2.10.exe" --console-messages

で、起動するとコンソールが表示されますが、これはエラーコンソールの内容がそちらに表示されるだけで、Pythonインタープリタのエラーメッセージの内容までが表示されるわけではありません。エラーコンソールを表示させていればそちらに表示されますので、あまり意味がありません。

3. Python-fu コンソールからコマンドを貼り付ける

 もう一つの方法としては、自分の書いたプログラムから、一文一文 Python-fu コンソールからコマンドを貼り付けてチェックするというやり方があります。文法エラーなどはこれでチェックするしかありません。ただプログラムが長くなるとこれで頭から確認するのは相当な手間になりますし、確認できることも限定されます。あくまでも限定的な動作確認のやり方と考えた方がよいと思います。

4. プラグインファイルがメニューに表示されない原因

 プラグインがメニューに表示されないと、どこが悪いのか途方に暮れてしまいます。しかしその原因は基本的に Register関数の与え方のミスです。

 一番多いのは実質的なメイン部分の関数名と、Registerで登録しておくべき関数名の不一致、スペルミスです。例えば、メインの関数名を def main() と定義していた場合、

regster関数の頭

register(
    "main",   ←関数名をそのまま入れる

 

それから、最後から2番目、メニュー表示位置指定の直前

    main, menu="<Image>/My Plugins/テスト" )

この(緑色に塗った部分の)三つの不一致が、表示されない大きな要因です。

 それから、当然ですが、Register関数のフォーマットミスがあると全く表示されません。どこか引数が欠けていないか、スペルミスがないか、大文字と小文字が違っていないか、全角と半角が変な風に混在していないか、ご確認ください。特に、意図しない打鍵ミスによるスペルミスは、本人が正しく打っていると思っていますので、非常に発見が難しいです。自分でも何時間も動かない原因を考えた挙句、結局原因は単純なスペルミスだったという経験は何度もあります。プログラミングエディタのVisulal Studio Code は、初めて出てくる変数名に下線を引いて表示してくれるので(つまり、意図しないところに下線が引かれた変数名が出てきたときは、スペルミスの可能性が大)、このようなエディタを活用するのも、ミスを発見するのに役立ちます。

 また Registerで指定している引数名と、メイン関数で指定している引数名がちゃんと一致しているかも確認してください。

 この対策として、Register部分のテンプレートを作って活用するというのも一案です。

 なお、以前も書きましたが、Register関数の間違いでプラグインが認識されない場合、修正したあと、GIMPを起動し直さないと認識されません。それ以外のコードの修正に関しては、GIMPを起動し直さなくても、コード変更後、プラグインを再度実行すればすぐ変更点が反映されます。

 

 なお、以下にエラー確認のサンプルコードとして、読み込んだ imageオブジェクトやdrawableの名称を gimp.messageで表示するコードを掲載します。このプログラムを動かす場合は、あらかじめ画像ファイルを読み込んでから起動してください。なおGIMPのメニューに My Pluginsという項目ができ、その下のテストからこのプログラムを起動することができます。

 テンプレートとして活用していただいても結構です。

---------------------

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from gimpfu import *
import os, glob

def input_objects_test(img, drawable):
    pdb.gimp_message_get_handler(ERROR_CONSOLE)
    gimp.message("image:")
    gimp.message(str(img))
    gimp.message("drawable:")
    gimp.message(str(drawable))
#    gimp.message("layer:")
#    gimp.message(str(layer))
    ismask = pdb.gimp_item_is_layer_mask(drawable)
    gimp.message("drawable is mask?")
    gimp.message(str(ismask))
    return

register(
    "input_objects_test",
    "オブジェクト取得テスト",
    "オブジェクト取得テスト",
    "Ohnishi, Yasuo",
    "Ohnishi, Yasuo",
    "2022_07_26",
    "オブジェクトを取得...",
    "*",      # Alternately use RGB, RGB*, GRAY*, INDEXED etc.
    [
#   get currect active image and drawable to "img" and "drawable"
    (PF_IMAGE, "img", "Input image", None),
    (PF_DRAWABLE, "drawable", "Input drawable", None),
#   (PF_LAYER, "layer", "Input layer", None), 
#   (PF_FILENAME, "filename", "入力ファイル名", ""),
    ],
    [],
    input_objects_test, menu="<Image>/My Plugins/テスト" )
main()