2021年10月2日土曜日

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

GIMP Script-Fu(14) GIMP 3.0 が来る前にやらなければいけない事 追補
でも、書いたのですが、 GIMP は 3 の時代を迎える為に、API の更新を迎えます。
内部もガラッと変わっていて、
Python の Script は、其の影響を諸に被ります。


Script-Fu は GIMP 本体? が変化への対応を行ってくれている為に、
然程、Script のコード上での変化は少ない形に抑えられています。
しかし、Python では、 本体の変化 と同じレベル の対応 が求められます。

GIMP 2.x での Python は、本体と Python 2 との間で、クッション的な仕組みがありましたが、
GIMP 3.x での Python は、Python 3 で 直接 本体と遣り取りする感じがします。
言葉を変えれば、 
C で書かれた各種機能 とほぼ同じ機能をストレートに使う様に変更されている、 と。
中間に存在したオブラート的なものは、便利だった反面、
維持の複雑化や問題内包や開発推進の弊害となっていたのでしょうか?。
単純明快な構造にする事で、再出発を図っていると思っています。
或いは、
技術的な観点から、
静的バインディングが 動的なものに置き換わっている、とも説明されます。
(普通の感覚では、何じゃ其れ?、ですけれども、 ね。)


さて、長~い 前置き は此れ位にして、 Python 。


四苦八苦し乍ら、 書いて見ました。
いや~、 大変でした。


Python Console が使える様になるのに、一苦労ですが、
Console 上で 道筋 を見付けてから、
実際に、スクリプトにして、配置し、動く様にするのが 苦難の道です。
分かっていない知識でですから、暗夜行路 そのもの!。
泥沼を匍匐前進!、 故に、口の中は 泥だらけ! の気分。
早く、立って歩ける様になりたいものです。  ;)

さて、やはり、第一歩は Console 。
基本的な import は済んだ状態に見受けられます。 (GIMP 2.99.7 Nightly)

Script では Image や Drowable は自動取得の上に渡されてスタートしますが、
Console では 自分で指定してやらないといけません。
書き方が変わっています。
image = Gimp.Image.get_by_id(n)
です。 n はタイトルバーに表示された画像番号で、1.0 なら 1 が入ります。
Layer 類も同様に記述して指定可能ですが、普通は別の手段で行う事が多い筈です。

そして、注意点は、大文字小文字を区別する事。
Gimp. と gimp. とは別物と判断されます。

尚、Console から dir(xxx) or help(xxx) と打って、概要を掴みましょう。
私は此れをファイルに保存して眺めています。
最低、
  dir(Gimp)
  dir(Gimp.Image)  help(Gimp.Image)
  dir(Gimp.Layer)  help(Gimp.Layer)
  dir(Gimp.Item)   help(Gimp.Item)
は見て置いた方が宜しいかと。
(ソレニシテモ、膨大な量に 慄き ます。)

そして、此れ等は Python に用意された GIMP の 内部機能 になります。
C で書かれた GIMP のコード自体を Python から操作するイメージです。

そして、画像操作の主要な機能は、
同じもの(同一機能)が pdb 詰まり Procedure Browser に用意されています。
Browser 上で Inner (内部 GIMP プロシジャー) と明記あるもの に相当します。
無論、Plug-ins 等、pdb 経由でしか、実行出来ないものもあります。

基本的には、どちらを使っても結果は同じ筈ですが、
Gimp Class もののを使う方が、(オーバーヘッドも少ない筈ですから)良いと思います。

pdb 経由では引数の中で Image や Layer を指定しますが、
Gimp Class では image.get_name() の様に、インスタンス名 image からアクセスします。
Gimp.Image.get_name() ではありません。
此の場合の戻り値は 文字列 そのもので返ります。

尚、冒頭の例、
Gimp.Image.get_by_id(1) では戻り値は、Gimp.Image object が返ります。
そう、 Object で、です。
例えば、<Gimp.Image object at 0x000001ad1599df80 (GimpImage at 0x000001ad15afd700)> 。
同様な例が多いので、Image や Layer 類なら、 
確認には、.get_name() を使うと良いでしょう。

同じ事を pdb 経由ですると、
>>> name = Gimp.get_pdb().run_procedure('gimp-image-get-name', [ image])
>>> name
<Gimp.ValueArray object at 0x000001ad1590eee0 (GimpValueArray at 0x000001ad15c2b3a0)>
>>> name.index(1)
'[DSC_0063] (インポートされた画像)'
>>>
こんな具合です。  そして、此れが、画像のタイトルバーの表示と一致します。
因みに、
name.index(0) には Gimp.PDBStatusType の enum GIMP_PDB_SUCCESS... が入っています。
ケースバイケースなので、一概には言えませんが、
Gimp Class を使った方が分かり易い気がします。

但し、
Gimp Class と pdb 経由で 戻り値 の格納形式が異なる事も多いので、
其処は要注意!ですね。

尚、現状では、pdb 経由の場合、
TypeError: cannot unpack non-iterable ValueArray object の ERROR が発生する事もあります。
開発途上! ですから、 暫し、様子を見ましょうか。
(例: Gimp.get_pdb().run_procedure('gimp-image-get-layers', [ image])  GIMP 2.99.7 commit 1373bec)
image.get_layers() なら、問題無しで通ります。



参考 上記の Cosole

GIMP 2.99.7 Python Console
Python 3.9.6 (default, Jul 12 2021, 05:46:11)  [GCC 10.3.0 64 bit (AMD64)]
>>> n=1
>>> image = Gimp.Image.get_by_id(n)
>>> image
<Gimp.Image object at 0x000001ad1599df80 (GimpImage at 0x000001ad15afd700)>
>>> image.get_name()
'[DSC_0063] (インポートされた画像)'
>>> type(image.get_name())
<class 'str'>
>>> name = Gimp.get_pdb().run_procedure('gimp-image-get-name', [ image])
>>> name
<Gimp.ValueArray object at 0x000001ad1590eee0 (GimpValueArray at 0x000001ad15c2b3a0)>
>>> name.index(1)
'[DSC_0063] (インポートされた画像)'
>>> Gimp.get_pdb().run_procedure('gimp-image-get-name', [ image])
<Gimp.ValueArray object at 0x000001ad159ba0a0 (GimpValueArray at 0x000001ad15adca40)>
>>> name.length()
2
>>> name.index(0)
<enum GIMP_PDB_SUCCESS of type Gimp.PDBStatusType>
>>> type(name.index(0))
<class 'gi.repository.Gimp.PDBStatusType'>
>>>
>>> num_layers, layers = Gimp.get_pdb().run_procedure('gimp-image-get-layers', [ image])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: cannot unpack non-iterable ValueArray object
>>> image.get_layers()
[<Gimp.Layer object at 0x000001ad159b8e00 (GimpLayer at 0x000001ad15bf1be0)>
>>>
>>> layers=image.get_layers()
>>> len(layers)
1
>>> layer1=layers[0]
>>> layer1.get_name()
'DSC_0063.JPG'
>>>



0 件のコメント:

コメントを投稿