スクリプトで実装という。
つまるところ単純にグループレイヤーの最下層のアルファ値でマスクを作り、その他の兄弟レイヤにマスクとして適用するというモノです。
最下層のレイヤを描き変え終わったら、このスクリプトを走らせてマスクを同期させる、という原始的なものでございます。
マスクをかけるレイヤを制限するには、必要なレイヤにだけマスクを作るか、リンク指定するなどして、スクリプト実行時にソレに合わせた適切なオプションを選択して実行してください。
なお、トップレベルレイヤでは大抵の場合、最下層が全不透明の背景であることが多いため、このsync-layergroup-maskは単純に機能しないように作ってあります。
その他、真下のレイヤのアルファ値と同期とかのスクリプトも一緒に混ぜてあります。
バグがあるとは思うんですが適当に修正してください(^^;)
from gimpfu import *
import re
SIBLING_PATTERN='^%s(-\S+)?$'
def python_fu_sync_layer_mask(a_img,a_drawable,src_layer,regexp_pattern):
if src_layer==None:
src_layer=a_img.active_layer
sync_layer_mask(a_img,src_layer,re.compile(regexp_pattern),None)
def python_fu_sync_layer_mask_of_sibling(a_img,a_drawable):
names=a_img.active_layer.name.split('-')
head=names[0]
sync_layer_mask(a_img,a_img.active_layer,re.compile(SIBLING_PATTERN % head),None)
def python_fu_sync_layer_mask_of_base(a_img,a_drawable):
names=a_img.active_layer.name.split('-')
head=names[0]
regexp=re.compile('^%s-base$' % head)
for bl in a_img.layers:
mo=regexp.search(bl.name)
if mo:
if bl==a_img.active_layer:
gimp.message("アクティブレイヤがベースレイヤです")
else:
sync_layer_mask(a_img,re.compile(SIBLING_PATTERN % head),bl,targets=(a_img.active_layer,))
return
gimp.message("ベースレイヤ(%s-base)は発見できませんでした" % head)
def python_fu_sync_layergroup_mask(a_img,a_drawable,limit_to_linked,limit_to_has_mask,apply_prev_mask):
cl=a_img.active_layer
if len(cl.children)>0:
target_layers=cl.children
elif cl.parent==None:
gimp.message("グループに所属するレイヤにのみ有効です")
return
else:
target_layers=cl.parent.children
cl=target_layers[-1]
sync_layer_mask(a_img,None,cl,targets=target_layers,
limit_to_linked=limit_to_linked,
limit_to_has_mask=limit_to_has_mask,
apply_prev_mask=apply_prev_mask,
force_other_mask=True)
def python_fu_sync_layer_mask_to_below(a_img,a_drawable,apply_prev_mask):
al=a_img.active_layer
if al.parent:
plst=al.parent.children
else:
plst=a_img.layers
curidx=pdb.gimp_image_get_item_position(a_img,al)
if curidx < len(plst):
sync_layer_mask(a_img,None,plst[curidx+1],(a_img.active_layer,),apply_prev_mask=apply_prev_mask)
else:
gimp.message("これより下にレイヤがありませんので、同期できません")
def sync_layer_mask(a_img,regexp,src_layer,targets,
limit_to_linked=False,limit_to_has_mask=False,
apply_prev_mask=False,force_other_mask=False):
"""
core function.
Arguments:
regexp -- the regular expression object.if this is None,all name should be match.
targets -- a sequence of target layers.if None,a_img.layers used.
Returns:
None
"""
if targets==None:
targets=a_img.layers
if src_layer.mask!=None:
src_mask=src_layer.mask
elif src_layer.has_alpha:
src_mask=pdb.gimp_layer_create_mask(src_layer,2)
else:
gimp.message("この作業には、レイヤ %s にマスクかアルファチャネルが必要です" % src_layer.name)
return
pdb.gimp_image_undo_group_start(a_img)
try:
ax,ay=src_layer.offsets
def do_sync(targets):
for cl in targets:
if cl!=src_layer:
if len(cl.children)>0:
do_sync(cl.children)
else:
if regexp:
mo=regexp.search(cl.name)
else:
flag_limit_linked=True
if limit_to_linked and not cl.linked:
flag_limit_linked=False
flag_limit_mask=True
if limit_to_has_mask and cl.mask==None:
flag_limit_mask=False
mo=(flag_limit_linked and flag_limit_mask)
if mo:
if cl.mask==None:
if force_other_mask:
new_mask=pdb.gimp_layer_create_mask(cl,1)
else:
new_mask=pdb.gimp_layer_create_mask(cl,2)
elif apply_prev_mask:
pdb.gimp_layer_remove_mask(cl,0)
new_mask=pdb.gimp_layer_create_mask(cl,1)
else:
pdb.gimp_layer_remove_mask(cl,1)
new_mask=pdb.gimp_layer_create_mask(cl,1)
pdb.gimp_layer_add_mask(cl,new_mask)
cx,cy=cl.offsets
pdb.gimp_channel_combine_masks(cl.mask, src_mask, 0, -cx+ax , -cy+ay)
pdb.gimp_layer_set_edit_mask(cl,0)
do_sync(targets)
finally:
pdb.gimp_image_undo_group_end(a_img)
if src_layer.mask!=src_mask:
gimp.delete(src_mask)
register(
"python_fu_sync_layer_mask",
"sync-layer-mask",
"指定された正規表現パターンに適合する名前のレイヤ間で、マスクを同期させる",
"dothiko",
"dothiko",
"apr 2015",
"<Image>/Python-Fu/mask/sync-layer-mask",
"RGB*,GRAY*",
[
(PF_LAYER,"src_layer","元レイヤ",None),
(PF_STRING,"regexp_pattern","正規表現パターン(pythonのreモジュールの書式で)","\S+"),
],
[],
python_fu_sync_layer_mask)
register(
"python_fu_sync_layer_mask_of_sibling",
"sync-layer-mask-of-sibling",
"アクティブレイヤの兄弟レイヤ間で、マスクを同期させる",
"dothiko",
"dothiko",
"apr 2015",
"<Image>/Python-Fu/mask/sync-layer-mask-of-sibling",
"RGB*,GRAY*",
[
],
[],
python_fu_sync_layer_mask_of_sibling)
register(
"python_fu_sync_layer_mask_of_base",
"sync-layer-mask-of-base",
"アクティブレイヤのマスクを、ベースレイヤのマスクで同期する",
"dothiko",
"dothiko",
"apr 2015",
"<Image>/Python-Fu/mask/sync-layer-mask-of-base",
"RGB*,GRAY*",
[
],
[],
python_fu_sync_layer_mask_of_base)
register(
"python_fu_sync_layergroup_mask",
"alpha-inherit-mask",
"アルファ相続的な動作で、グループの最後尾のアルファと各レイヤーのマスクを同期させる",
"dothiko",
"dothiko",
"apr 2015",
"<Image>/Python-Fu/mask/sync-layergroup-mask",
"RGB*,GRAY*",
[
(PF_BOOL,"limit_to_linked","リンクされたレイヤに限定",False),
(PF_BOOL,"limit_to_has_mask","現時点でマスクを持つレイヤに限定",True),
(PF_BOOL,"apply_prev_mask","対象レイヤが既にマスクを持つ場合、同期前にマスクを適用する",False),
],
[],
python_fu_sync_layergroup_mask)
register(
"python_fu_sync_layer_mask_to_below",
"sync-layer-mask-to-below",
"真下のレイヤの不透明部分をマスクとして同期させる",
"dothiko",
"dothiko",
"apr 2015",
"<Image>/Python-Fu/mask/sync-layer-mask-to-below",
"RGB*,GRAY*",
[
(PF_BOOL,"apply_prev_mask","対象レイヤが既にマスクを持つ場合、同期前にマスクを適用する",False),
],
[],
python_fu_sync_layer_mask_to_below)
main()
if __name__ == '__main__':
pass