これはこれで面白そうなので、いつか取り組もうとは思うのですが、取り急ぎScript-Fuで書き直すことを考えたいと思います。
自分の使うスクリプトは条件分岐やループがほとんどない、関数をただ並べたような代物が多いので比較的簡単に移植出来るのではと楽観的に考えています。
スクリプト言語自体に慣れていないのでコンソールで1行1行関数を実行して確認しながら進めてみたいと思います。
それでは、選択範囲を別レイヤーに切り出すスクリプトを移植するために各関数の確認作業を始めます。
選択範囲の座標を取得
> (define img (aref (car (cdr (gimp-image-list))) 0))
img
> (define layer(car (gimp-image-get-active-layer img)))
layer
> (gimp-edit-fill layer 0)
(#t)
> (gimp-selection-bounds img)
(1 147 102 260 207)
まず、gimp-selection-boundsを実行するため引数となるimageオブジェクトが必要となります。
コンソールで実行するために事前に処理を実行します。
define img…とdefine layer…は現在開かれているimageオブジェクトとlayerオブジェクトを取得しています。
gimp-edit-fill layerは前景色で塗りつぶしです。こちらは確認のため実行しています。
続いてgimp-selection-boundsを実行したところ戻り値は
(1 147 102 260 207)
となりました。
1番目は選択範囲の有無で、結果から1がありで0が無しだと思われます。
2番目はx1
3番目がy1
4番目がx2
5番目がy2
の座標がセットされています。
ちなみになげなわ選択で円の様に範囲選択していますが、取得できる座標はx1-x2 y1-y2ですので矩形の情報になります。
このままだと使いづらいので戻り値を変数にセットします。
(define sb (gimp-selection-bounds img))
sb
選択範囲の有無を変数にセット
code>(define non_empty (car sb)) non_empty
x1を変数にセット
code>(define x1 (car (cdr sb))) x1
y1を変数にセット
code>(define y1 (car (cdr (cdr sb)))) y1
x2を変数にセット
code>(define x2 (car (cdr (cdr (cdr sb))))) x2
y2を変数にセット
code>(define y2 (car (cdr (cdr (cdr (cdr sb)))))) y2
もっと良い方法があると思いますが、とりあえずこれで戻り値が各変数に収まりました。
レイヤーにアルファチャンネルを追加
(gimp-layer-add-alpha layer)
(#t)
引数にlayerをセットしています。実行したところアルファチャンネルが追加されていました。
レイヤーの複製
コピー処理
(define new_layer (car (gimp-layer-copy layer 1)))
new_layer
引数1はアルファチャンネルをコピーするフラグ1がTRUE
new_layerはオブジェクトではなく数値のようです。
詳しく理解できていないのですが、car処理を挟まないと次の挿入処理に使う引数で蹴られてしまいました。
挿入処理
python-fuではimageオブジェクトにメソッドでadd_layer()としていましたが、Script-Fuではgimp-image-insert-layer関数を使ってみます。
(gimp-image-insert-layer img new_layer 0 0)
(#t)
レイヤーがコピーされていました。
レイヤーのオフセットを取得
(define of (gimp-drawable-offsets new_layer))
(define x0 (car of))
(define y0 (car (cdr of)))
レイヤーサイズの変更
(gimp-layer-resize new_layer (- x2 x1) (- y2 y1) (- x0 x1) (- y0 y1))
レイヤーサイズの計算で引き算しているのですがマイナス演算子の位置が先頭になります。
また、各計算も()で括ってあげます。
選択範囲外を透明で塗りつぶし
(gimp-selection-invert img)
次に透明色で塗りつぶし処理。
(gimp-edit-fill new_layer 3)
元レイヤーの選択部分を切り抜き
処理は同上。
元レイヤーの選択範囲を透明色で塗りつぶし
(gimp-edit-fill layer 3)
元レイヤーをアクティブに変更
(gimp-image-set-active-layer img layer)
スクリプトの登録
スクリプトの保存場所:%Userprofile%\AppData\Roaming\GIMP\2.10\scripts
ファイル名:cut-new-layer.scm
;
; 選択範囲をレイヤーに切り出すスクリプト
;
(define (script-fu-cut-new-layer img layer)
; Undo記録開始
(gimp-undo-push-group-start img)
; 選択範囲座標の取得
(define sb (gimp-selection-bounds img))
(define non_empty (car sb))
(define x1 (car (cdr sb)))
(define y1 (car (cdr (cdr sb))))
(define x2 (car (cdr (cdr (cdr sb)))))
(define y2 (car (cdr (cdr (cdr (cdr sb))))))
; アルファチャンネルを追加
(gimp-layer-add-alpha layer)
; レイヤーの複製
(define new_layer (car (gimp-layer-copy layer 1)))
(gimp-image-insert-layer img new_layer 0 0)
; オフセット取得
(define of (gimp-drawable-offsets new_layer))
(define x0 (car of))
(define y0 (car (cdr of)))
; レイヤーサイズの変更
(gimp-layer-resize new_layer (- x2 x1) (- y2 y1) (- x0 x1) (- y0 y1))
; 選択範囲外を透明で塗りつぶし
(gimp-selection-invert img)
(gimp-edit-fill new_layer 3)
; 元レイヤーの選択部分を切り抜き
(gimp-selection-invert img)
(gimp-edit-fill layer 3)
; 元レイヤーをアクティブに変更
(gimp-image-set-active-layer img layer)
; Undo記録終了
(gimp-undo-push-group-end img)
(gimp-drawable-update layer 0 0 (car (gimp-drawable-width layer)) (car (gimp-drawable-height layer)))
(gimp-displays-flush)
)
(script-fu-register "script-fu-cut-new-layer"
"<Image>/Filters/My/レイヤー切り出し..."
"選択範囲をレイヤーに切り出します。"
"Maywork"
"Copyright 2020, Maywork"
"04/06/2022"
"RGB* GRAY*"
SF-IMAGE "Input Image" 0
SF-DRAWABLE "Input Layer" 0
)
実行
メニュー「フィルター」→「My」→「レイヤー切り出し」を実行
画像自体は変化していないようにみえますが、レイヤーが二つに増えています。
選択範囲を切り出したレイヤー
範囲選択された部分が収まる矩形に合わせたレイヤーサイズなっています。
また範囲外は透明になっています。
切り抜かれた元レイヤー
選択範囲分が透明になっています。
以上
コメント