先日アップデートした画像ファイルをレイヤーマスクとして読み込むプラグインですが...
yasuo-ssi.hatenablog.com GIMP / Python プログラミングは結構難しいので、今回、GIMP / Pythonプログラマーの方に参考になるように、コードの解説をつけます。
---------------
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 以上UTF-8を有効にしたPythonプログラムという宣言
# Plug-in: Open file as mask
# Version: 0.12
# Date: 2022_07_25
# (以下コメント略)
from gimpfu import *
import os, glob
# 以上読込むライブラリーの宣言
def import_file_as_mask(img, drawable, filename):
# 実質的なメイン部分の宣言
# 引数は、
img: 現在アクティブなimageオブジェクト
drawable: 現在アクティブな drawable (レイヤー or マスク)
filename: ファイル名
pdb.gimp_message_get_handler(ERROR_CONSOLE)
# メッセージはエラーコンソールに出力する指定
ismask = pdb.gimp_item_is_layer_mask(drawable)
# drawableがマスクかどうかを調べる
if ismask == TRUE: # もし drawable がマスクなら
layer_active = pdb.gimp_layer_from_mask(drawable)
# マスクの属するレイヤーを取得
drawable = layer_active
# レイヤーを drawableに代入
# これで drawable は以下レイヤーに統一
pdb.gimp_image_undo_group_start(img)
# 取り消す場合の範囲ここから始まる
try:
imgload = pdb.gimp_file_load(filename, filename)
# filenameで指定したファイルをimgloadに読み込む
disp = pdb.gimp_display_new(imgload)
# imgloadの画像を新しいファイルとして表示する
except Exception, error:
print error
pdb.gimp_edit_copy(imgload.layers[0])
# 読んだ画像の最初のレイヤーをコピーする
if pdb.gimp_drawable_has_alpha (drawable) == FALSE:
# もしマスクをつけたいレイヤーにαチャンネルがなければ
pdb.gimp_layer_add_alpha (drawable)
# αチャンネルを追加する
maskexist = pdb.gimp_layer_get_mask(drawable)
# マスクをつけたいレイヤーのマスクの有無をmaskexit変数に保存
# gimp.message(str(drawable))
# デバッグ用のメッセージ表示 (現在コメントアウト)
try:
mask = pdb.gimp_layer_create_mask(drawable, ADD_WHITE_MASK)
# 地が白のマスク画像をマスクをつけるレイヤーに追加
if mask != None:
# マスク画像ができていれば...
pdb.gimp_layer_add_mask(drawable, mask)
# マスク画像をレイヤーにマスクとして追加
# 注意! gimp_layer_create_mask だけではまだレイヤーにマスクとして追加されない!!
except Exception, error:
print error
# 既にマスクがあればエラーメッセージを表示してマスク付加をスキップ
pdb.gimp_layer_set_edit_mask(drawable, TRUE) # Activate Mask Edit Mode
# 今つけた(アクティブな)マスクを編集モードにする
floating_sel = pdb.gimp_edit_paste(drawable.mask, False)
# クリップボードのイメージをフローティング選択範囲としてマスクに貼り付け
pdb.gimp_floating_sel_anchor(floating_sel)
# フローティング選択範囲をマスクに固定
pdb.gimp_layer_set_edit_mask(drawable, FALSE)
# マスク編集モードをオフ
pdb.gimp_display_delete(disp)
# 読み込んだ画像の表示を削除
pdb.gimp_image_undo_group_end(img)
# 取り消す場合の範囲ここまで
return
register(
"Open_file_as_mask",
"Open file as mask",
"ファイルをマスクとして読込む",
"Ohnishi, Yasuo",
"Ohnishi, Yasuo",
"2021-22 Ver 0.12",
"マスクとして読込む...",
"*", # Alternately use RGB, RGB*, GRAY*, INDEXED etc.
[
# 現在アクティブな image と drawable を "img" と "drawable" として読込む
# また読み込む画像ファイル名をダイアログから指定する
(PF_IMAGE, "img", "Input image", None),
(PF_DRAWABLE, "drawable", "Input drawable", None),
(PF_FILENAME, "filename", "入力ファイル名", ""),
],
[],
import_file_as_mask, menu="<Image>/File/Open" )
main()
---------------
なお、2021年6月のアップデートで、複数のファイルが読み込まれていると、指定したファイルのレイヤーではなく、最後に読み込んだファイル (image オブジェクト) のアクティブなレイヤーに対しマスクがかかってしまうという現象を直せなかったのは、指定したアクティブなレイヤーを読み込むのに gimp-image-get-active-layer API を使ってたためのようです。
本来ならこれで問題ないはずなのですが、複数のファイルを読み込んだ状態で、途中で他のファイルを読み込んだり複雑な操作を行ったりして、一時的にアクティブな imageオブジェクトが移ると、最終的にアクティブな image オブジェクトが最後に読み込んだ image になってしまうようです。その際、gimp-image-get-active-layer API で読み込んでおいた drawable (レイヤー) も予め指定しておいた image の drawable ではなく、その時点でアクティブな image のアクティブな drawable に移ってしまうようです。つまり、gimp-image-get-active-layer API で読み込んでおいたポインタは、どうやら常にその時点でアクティブな image のアクティブな drawable を示すようです。これが仕様なのか、それとも複雑な操作をやったときのみ発生するバグなのかは、まだ追求できていません。これを、drawable が他のものに入れ替わらないようにするには、APIでdrawableを読まずに、Registerから drawable を読み込んでおく必要があるようです。
改訂した本プラグインでも、コードに一切指定していないにもかかわらず、実行後は、なぜか最終的にアクティブな image が最後に読み込んだ image になってしまいます。なお、プロシジャーブラウザで調べられる GIMP のAPIの中には、現在アクティブなimageを設定するAPIは存在しません。