2021年10月9日土曜日

GIMP Script-Py (番外) GIMP 3.0 が来る前にやってみよう 後半

GIMP Script-Py (番外) GIMP 3.0 が来る前にやってみよう 前半 の続きです。
Python Console で筋道を着けたなら、
いよいよ、ファイルにして、 Script に纏めます。
実は、此れが、 何台 ... いいえ此れタイプミス ... 難題!。


前回 、書くのを忘れたのですが、
GIMP 3 の API に慣れる為にも、Python Console を叩き捲って下さい。
そのうち、 馴染んで来ますって!。  ;)

GIMP 2.10 等で経験の有る方は、暫しの奮闘で馴染めるかも知れません。
但し、其の経験が裏目に出て、
Gimp. を gimp. と書いて仕舞ったり、
インスタンス img のみタイプして、Object の参照が返り、慄いたり、
と、 最初は散々かも。

そして、 Console で動く道筋を見極めれば、
しめたもの! でした、 嘗ては。

そう、其れは前触れにしか過ぎません!。
恐ろし! の Plug-ins 登録(記述)が控えています。
まるで、 百叩きの刑。
何かのアニメの台詞ではありませんが、 「死ぬ程、鍛えろ!」 です。


では、 百叩きの刑 と参りましょう。  ;)


出来上がったロジックから、体裁を整えて行きます。
以下に Image 及び Layer のみを引数に取る例を示します。
はい。  百叩き が済んだ後の 結果 になります。
ロジックの例として、単に、引数の Message を表示するだけにします。

 注:~ GIMP 2.99.10 限定。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Python for GIMP 2.99.7 +

import gi
gi.require_version('Gimp', '3.0')
from gi.repository import Gimp
gi.require_version('GimpUi', '3.0')
from gi.repository import GimpUi
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gio

import gettext
_ = gettext.gettext
def N_(message): return message

import sys


# Procedure 関数(関数名・引数・処理)
def shiro_dialog_args0_test_api3(procedure, run_mode, image, n_drawables, drawables, args, data):
  # Pre-Start of proc for GIMP3
  config = procedure.create_config()
  config.begin_run(image, run_mode, args)

  if run_mode == Gimp.RunMode.INTERACTIVE:
    GimpUi.init('python-fu-shiro-dialog-args0-test-api3')
    dialog = GimpUi.ProcedureDialog.new(procedure, config)
    #dialog.get_color_widget('color', True, GimpUi.ColorAreaType.FLAT)
    dialog.fill(None)
    if not dialog.run():
      dialog.destroy()
      config.end_run(Gimp.PDBStatusType.CANCEL)
      return procedure.new_return_values(Gimp.PDBStatusType.CANCEL, GLib.Error())
    else:
      dialog.destroy()

  # Start

  # <<Your Scripting Here!>>
  # Sample
  img = image
  lyr = drawables[0]
  Gimp.message("Dialog Args ---------   ¥n" + ¥
               "   image : (id#" + str(img.get_id()) + ")  " + img.get_name() + "     ¥n" + ¥
               "   drawables count : " + str(n_drawables) + "     ¥n" + ¥
               "   layer : (id#" + str(lyr.get_id()) + ")  " + lyr.get_name() + "     ¥n" + ¥
               "   -------------   ¥n"
              )

  # End of proc for GIMP3
  config.end_run(Gimp.PDBStatusType.SUCCESS)
  return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())

class ShiroDialogArgs0TestApi3 (Gimp.PlugIn):
    ## Parameters ##
    # __gproperties__ = {}

    ## GimpPlugIn virtual methods ##
    def do_query_procedures(self):
        self.set_translation_domain("gimp30-python",
                                    Gio.file_new_for_path(Gimp.locale_directory()))

        return [ 'python-fu-shiro-dialog-args0-test-api3' ]

    def do_create_procedure(self, name):
        procedure = Gimp.ImageProcedure.new(self, name,
                                            Gimp.PDBProcType.PLUGIN,
                                            shiro_dialog_args0_test_api3, None)
        procedure.set_image_types("RGB*");
        procedure.set_sensitivity_mask (Gimp.ProcedureSensitivityMask.DRAWABLE |
                                        Gimp.ProcedureSensitivityMask.DRAWABLES)
        procedure.set_documentation (N_("Args In Dialog Test (image and drawables Only)"),
                                     "Args In Dialog Test For GIMP 2.99.x",
                                     name)
        procedure.set_menu_label(N_("Dialog Args0 Test Api3"))
        procedure.set_attribution("ShiroYuki_Mot",
                                  "Copyright 2021- ShiroYuki_Mot",
                                  "2021/09/30")
        procedure.add_menu_path ("<Image>/Script-Py/Test/")

        # procedure.add_argument_from_property(self, "<<arg_name_n>>") ...

        return procedure

Gimp.main(ShiroDialogArgs0TestApi3.__gtype__, sys.argv)

そう、 Console では たったの6行 Gimp.message( が こんなのに 化ける訳です。
6行は、上の例では 青い文字 にしてあります。
其の直前に、変数を読み替えているのに注目して下さい。

Code 見てると 気が狂って来そうですね。
でも、 引数追加が無い 此のケースは まだ 単純 です。
通常は、幾つかの 引数 パラメータ を採るのが 殆ど でしょうから。

しかし、昔のと違い 現状の GIMP 2.99.7 (Nightly) では 基本的なもの しか、扱えないのかも。
私の知識が足らないからかも知れませんが ... 。

基本としては、 整数・実数・文字列・真偽 の4つ。
そして、 Official (foggify.py) で示されていた 色 color の扱い を加え、5種類。
以前の PF_OPTION 等は 整数値で返りますから、まぁ、対処は可能ですけれど。
しかし、 現状の Nightly では 幾つか 挙動に疑問を覚える動作をします。
使え無い と迄は行きませんが、
きっと、 本来の 狙った動き では無い気がします。
開発途上版で、且つ、Nightly な訳ですから、 文句は言いません。
今後に期待!。  ;)

注目点は、
自分で決めた Procedure Name が 色々と変化する事。
Python の Rule に従い、全て小文字になったり、大文字が混ざったり、と。
上の例では 赤い文字 にしてあります。
融通も利く筈ですが、原則には従って置く方が Better だと思います。
pdb 登録名は python-fu- から始めるのが お勧め の筈。
  尚、命名の 単語連結は '_' が基本ですが、pdb 用文字列のみ '-' になるのは注意しましょう。
  そして、class 名 での単語連結は '_' を省き、大文字でスタートします。

  おっとぉ、 上の例では メニュー表示名迄、赤くして仕舞いました。  ご愛嬌。


さて、
此の投稿で、引数を加えた例を示そうとしたのですが、
先の理由から、見送りにします。

  一応、現状 (Nightly 2.99.7 commit 1373bec6 Pipeline#303256) で、
  稼働可能な Script を 以下の 別 Blog にアップして置きます。
  初期値の反映や、'nick' 表示 等に 疑問を感じますが、
  一応、動かせるものは作れる気がします。

別 Blog リンク:  準備出来次第 公開  注:~ GIMP 2.99.10 限定。
  GIMP Script-Py Shiro_Dialog_Args6_Test_API3

  画像のみ、此処にも貼って置きましょうか。



ね!、 GIMP 2.99(3.0) の Python 、難しいですね。  :O
  


[2021/10/21] リンクを追記 やっと公開しました。
[2022/08/30] GIMP 2.99.12 で変更があり、上記 Script は動きません。

9 件のコメント:

  1. 貴重な情報の公開をありがとうございます。
    現在、自作のGIMP2.*用のPythonスクリプトを、2.99 / 3.* 用に移行させようと考えていますが、GIMP 3.*では大幅に仕様が変わってしまうようなので、頭を抱えています。

    ところで、GIMP 2.99以降のPythonスクリプトを作成するにあたって、これはぜひ読んでおくべきというネット上の記事がありましたらご教示いただけますと幸いです。春先に自分で検索してみた時は、英文記事も含めて、これはと思う記事が探せなくて、非常に困ったのですが...

    返信削除
    返信
    1. 大西 康雄 さま コメントありがとうございます。

      ドキュメントは現在存在しません。
      GIMP の開発第一人者のおひとり Jehan さまは、
      GIMP 3 の登場迄には How To を書くとおっしゃているのですが ... 。

      公式の GIMP 2.99 に含まれる Python Scripts が最善の雛形。

      GIMP 2.10,x からの移行であるなら、
      先ずは、2.10 を --verbose オプション付きで動かし、
      Warning が出ないか確認して下さい。 其れが最初。
      次に、ロジックのみにしたものを、
      2.99 の Console で動く迄、奮闘です。
      最後が、此の投稿の様に 体裁を整える です。

      検索なさるなら、2021/08 以降で無いと 不正確 だと思います。
      GIMP 2.99.7 以降で Python がちゃんと動く様になりましたが、
      現在でも、不確定と思われる内容を含んでいます。
      https://gitlab.gnome.org/GNOME/gimp/-/issues/7106

      ご参考迄に。
      私の gimp-developer-list への質問に対する Jehan さまの回答がこちらです。 2021/08/24
      有益な内容を含んでいる筈です。
      https://mail.gnome.org/archives/gimp-developer-list/2021-August/msg00013.html

      削除
  2. ご回答、ありがとうございます。

    >公式の GIMP 2.99 に含まれる Python Scripts が最善の雛形。

    やっぱり...

    とりあえず、リンクのご紹介ありがとうございます。

    しかし、できれば pdbを使わないほうが良いということですね...
    とはいえ、自分のコード、pdb てんこ盛りなので頭痛いです。
    ダイアログを開くのもregisterでの記述頼みなので...

    返信削除
    返信
    1. pdb の適否は個人的な感想です。
      何よりも、動く事が一番かと。 他の方の Code を見ていると、pdb で書いた後、Gimp Class に書き直している例も見ました。
      自分で書いている Program (後述)でも、ある程度は置換していますが、まだ、ほんの ひとかけら です。

      2.99 Console でロジックを検証 については、以下の投稿をご覧下さい。
      https://shiroyuki-mot-says.blogspot.com/2021/10/gimp-script-py-extra-for-api3-1of2.html

      尚、前にも書いた様に、GIMP 2.10.x では 旧 API も許容していましたが、GIMP 2.99 では厳密になり、弾かれる筈です。
      其の為に、既存からの移行では、2.10.x での --Verbose チェックは必須と考えて下さい。
      Script-Fu での一例:https://shiroyuki-mot-says.blogspot.com/2019/07/gimp-script-fu-14.html

      因みに、
      どの位のコード量(行数)ですか? また、register はひとつだけ(複数を定義していない)ですか?。 
      更に、PF_??? はどんな種類を書いてありますか?。
      其れを書いたのは何時頃(GIMP Version で言えば)ですか?。
      其れに依っては、今、書いてある 暫定 Program で Migration(移行・変換)が可能かも知れません。
      参照:https://shiroyuki-mot-says.blogspot.com/2021/11/gimp-script-migration-program-part2.html

      削除
  3. 大西です。

    ありがとうございます。

    コードの長さは短いものは50行弱、長いものだと80行程度です。

    PF*は
    PF_FILENAME, PF_FILE, PF_IMAGE,PF_DRAWABLE,PF_STRING,PF_OPTION
    といったところです。
    GIMP Versionは 2.10.20以降で作成しています。

    返信削除
  4. あと
    registerは1つのみです。

    返信削除
    返信
    1. register ひとつ との事なので、移行 も可能な気はしますが、
      基本の4形 int float string bool 以外は手作業で直す必要があり、
      PF_FILENAME PF_FILE の部分の UI が私には分かりません。
      今の Program では <<argType>> <<vals>> 等に一旦変換され、其れを直せないので、先に行けないのです。
      暫定的に文字列(String 手入力/コピペ対応)で扱うなら、動きますが、
      其れを動くと呼べるか疑問ですね。
      個人的に、PF_FILE 系は使っていないので、全く調べていないのです。

      もし、何か情報を得たならば、ご連絡戴けると嬉しいです。

      削除
  5. そうですか。残念です。
    GIMP2.99の現状だと、各プロセスがどのように呼び出されるのか (おそらくGimp.mainでclassを読み込んで、def で定義されたプラグインを呼び出すのでしょうが)、さらに引数がどのようなルールによって引き継がれるのかがよく分からないので、もう少し情報が公開されるのを待つしかないように思われます。

    >今の Program では <> <> 等に一旦変換され、其れを直せないので、先に行けないのです。

    おっしゃる通りかと...

    返信削除
    返信
    1. >今の Program では <> <> 等に一旦変換され、其れを直せないので、先に行けないのです。
      >今の Program では <<argType>> <<vals>> 等に一旦変換され、其れを直せないので、先に行けないのです。

      < > は Blog Comment (html) では Tag と解釈されるので、
      &lt; &gt; と記述しないと 変な表示 に化けます。

      さて、本題。

      >各プロセスがどのように呼び出されるのか
      GIMP 本体とは別の独立した Python.exe (C:¥Program Files¥GIMP 2.99¥bin¥python.exe) が .py 等を引数に取って(子プロセス)起動しますが、Script の引数を直接でではありません。

      >引数がどのようなルールによって引き継がれるのか
      其れが 本投稿での スクリプト記述 になります。
      詳細は GIMP の C Code と同じ仕組みを Python Class から呼び出していると思います。 master/libgimp 辺りか参考になるか?。

      削除