2018年2月18日日曜日

GIMP Script-Fu (11) レイヤー情報を取得 1

GIMP の 我が ちょんぼ に絡んで、
レイヤーの微妙な ずれ を 目視 出来ないか考えていました。
そうだ!、 数値で見られる様にすればいいんだぁ!。
斯くして、久しぶりの Script-fu との格闘が始まりました。


画像は必ずひとつのレイヤーを持ちます。
画像編集でレイヤーを削除して 0 個 なし にしても、保存は出来ませんね。

これに対して、グループはレイヤーを持たない形も OK です。
そして、ネスト(子を更に持つ)する事も可能です。

この事に注意すれば、画像とグループの構造は酷似しています。
全レイヤーを対象にする場合、
似たプログラミング手法を取れますが、
レイヤーを取得するのに、
 画像は   (gimp-image-get-layers imageID)
 レイヤーは (gimp-item-get-children layerID)
である事に注意すれば良い事になります。

つまり、ふたつの 関数が必要ですね。
或いは、
変数を用意し、
最初に1回だけ、imageID を対象にし、次回からは layerID で、と、
条件分岐する事で ひとつに纏めても良いでしょう。

その場合、 ネストして再帰的な処理になる事も留意点です。


何時もながらの 動けば良し! レベルですので、
Script-fu いいえ Scheme や Lisp を書き慣れた方がご覧になれば お笑い種 のものですが ... 。


それでは、
仕上がっていない状態で掲載しましょう。

試しに、
全レイヤーを対象に、グループも展開し、そのレイヤー名を表示するものです。
表示順は GIMP の レイヤー ダイアログに従い、下から上へ重ねて表示する前提です。
また、完成版ではないので、
利用にあたっては、 Script-fu コンソール を開き、
事前に 固定名の変数 str を設定し 値を "" にした上で、 
画像番号等を指定の上実行して、 事後に str を表示させる必要が有ります。
(画像番号 1:この場合 , レイヤー番号 0 :不要・固定 , 条件分岐用:TRUE , 表示用文字変数 が引数です。).


   GIMP Script-Fu Console
.
> (define str "")
str
> str
""
> (script-fu-shiro-test-all-layers-loop-top 1 0 TRUE str)
()
> str
"Layer Group #1\nLayer Group\nLayer #3\nLayer #2\nLayer Group #2\nLayer #4\nLayer #1\nLayer\nBack Ground\n"

コンソール上では文字列中の改行が有効化されずに、
フォントもプロポーショナルな場合が多いと思いますので、
もうひと捻り が必要なのですが ... 。
また、階層を表す 段落下げ にも対応していないので、 親子関係が不明瞭ですし ... 。

一応、この全コードを。
但し、このままでは広域変数と局所変数の絡みで、上手く行きません。  なので、文字色は薄く。.
その辺りは、次回に。

(define (script-fu-shiro-test-all-layers-loop-top
  ;引数
 img
 layer0
 isTop
 str  ; Not in Sub Local
            )

  ;処理
   (script-fu-shiro-test-all-layers-loop img layer0 isTop)

)

(define (script-fu-shiro-test-all-layers-loop
  ;引数
 img
 layer0
 isTop
 ;str  ; Not Local
            )

  ;処理
  
   (let* (
           (topCounter 0)
           (topLayers '())
           (each-str "")
           ;(isTop TRUE)
         )

         ; Get All Layers or Children
         (if (= isTop TRUE)
            ; Top (First)
            (begin
               (set! topCounter (car (gimp-image-get-layers img)))
               (set! topLayers (cadr (gimp-image-get-layers img)))
               (set! isTop FALSE)
            )      ; End begin
            ; Group
            (begin
               (set! topCounter (car (gimp-item-get-children layer0)))
               (set! topLayers (cadr (gimp-item-get-children layer0)))
            )      ; End begin

        )       ; End if


         ;Top Loop
         (while (>= topCounter 1)

            ; Is Group ?  First Get Children
            (set! layer0 (vector-ref topLayers (- topCounter 1)))
            (if (= (car (gimp-item-is-group layer0)) 1)
               (begin
                  ; Recursion Call
                  (script-fu-shiro-test-all-layers-loop img layer0 FALSE)
               )
            )

            ; Get Each Layer Inf.
            (set! each-str (car (gimp-drawable-get-name layer0)))
            (set! str (string-append
                              each-str
                              "\n"
                              str
                      ))
     
            ; for Next
            (set! topCounter (- topCounter 1))

         )            ; End while Sub

   )
)

はい。
何とか動くものが出来ました。  :)
でも、 使わないで下さい .
使えそうなものは 次回 に。

使わないで!の理由は、文字列取得が今回の目的だからです。
もし、グループを含む全レイヤーに何かするのなら、参考にはなるかも (良い例ではないが) です。.



[2018/02/23] 次回をリンクに 02/24 公開予定。.

0 件のコメント:

コメントを投稿