#1.はじめに
GIMP Python-Fuで不透明部分を選択してマスクを作成する - Qiitaで一緒に行えばよかったですが、マスクの削除も必要だったので追加しました。
GIMP2.10で動作確認をしています。
#2.実行結果
GIMP Python-Fuで不透明部分を選択してマスクを作成する - Qiitaの後に、マスクを削除してオレンジ円を描画しています。マスクがないため、オレンジ円が全て描画されます。
#3.追加部分
マスクの削除とオレンジ円の描画です。
# マスクをレイヤーから削除する
pdb.gimp_layer_remove_mask(transparent_layer, MASK_APPLY)
# オレンジ円
set_color(255, 127, 0, 1.0)
make_path_relative2(image, 400, 370, points, 3, TRUE)
#4.スクリプト全体
# Python-Fu のサンプル・スクリプト
# GIMP の Python-Fu コンソールにコピペして実行してください
# 画像データの作成
## 指定したサイズで画像データを作成する
### width : 画像データの幅 (px)
### height : 画像データの高さ (px)
def create_image(width, height):
# 画像データを生成
return gimp.Image(width, height, RGB)
# レイヤーの追加
## 指定した名前のレイヤーを新規に作成し、画像データに挿入する
### image : レイヤーを追加する画像データ
### name : 新規に作成するレイヤーの名前(文字列)
def add_layer(image, name):
# レイヤーの作成に必要なパラメータ
width = image.width
height = image.height
type = RGB_IMAGE
opacity = 100
mode = NORMAL_MODE
#
# パラメータをもとにレイヤーを作成
layer = gimp.Layer(image, name, width, height, type, opacity, mode)
#
# レイヤーを背景色で塗りつぶす(GIMP のデフォルトの挙動に合わせています)
layer.fill(1)
#
# 画像データの 0 番目の位置にレイヤーを挿入する
position = 0
image.add_layer(layer, position)
#
return layer
def add_layer_transparent(image, name):
# レイヤーの作成に必要なパラメータ
width = image.width
height = image.height
type = RGBA_IMAGE
opacity = 100
mode = NORMAL_MODE
#
# パラメータをもとにレイヤーを作成
layer = gimp.Layer(image, name, width, height, type, opacity, mode)
#
# レイヤーを透明色で塗りつぶす
layer.fill(TRANSPARENT_FILL)
#
# 画像データの 0 番目の位置にレイヤーを挿入する
position = 0
image.add_layer(layer, position)
#
return layer
# 描画する色を変更する
## パレットの前景色を変更して描画色を設定する
### r : 赤要素 (0-255)
### g : 緑要素 (0-255)
### b : 青要素 (0-255)
### a : 透明度 (0-1.0)
def set_color(r, g, b, a):
color = (r, g, b, a)
pdb.gimp_context_set_foreground(color)
def set_bg_color(r, g, b, a):
color = (r, g, b, a)
pdb.gimp_context_set_background(color)
# 描画する線の太さを変える
## ブラシのサイズを変更して線の太さを設定する
### width : 線の太さ
def set_line_width(width):
pdb.gimp_context_set_brush_size(width)
# アンチエイリアスを設定する
## アンチエイリアスを設定する
### antialias : TRUE:有効、FALSE:無効
def set_antialias(antialias):
pdb.gimp_context_set_antialias(antialias)
# 画像の表示
## 新しいウィンドウを作成し、画像データを表示する
### image : 表示する画像データ
def display_image(image):
gimp.Display(image)
# パス作成
## パスを作成
### image : レイヤーを追加する画像データ
### points : パス座標
### mode : 0:描画しない、1:閉じないストローク(初期値)、2:閉じるストローク、3:塗りつぶし
### delete_path : TRUE:パスを削除する(初期値)、FALSE:パスを残す
def make_path(
image,
points,
mode=1,
delete_path=TRUE,
):
""" パスを作成する。 """
#
# フラグ設定
#
is_draw = FALSE
is_closed = FALSE
is_fill = FALSE
is_stroke = FALSE
if mode == 1: # 閉じないストローク
is_draw = TRUE
is_closed = FALSE
is_fill = FALSE
is_stroke = FALSE
elif mode == 2: # 閉じるストローク
is_draw = TRUE
is_closed = TRUE
is_fill = FALSE
is_stroke = FALSE
elif mode == 3: # 塗りつぶし
is_draw = TRUE
is_closed = TRUE # TRUE/FALSEどちらでも変わらない
is_fill = TRUE
is_stroke = FALSE
elif mode == 4: # 閉じないストローク(アンチエイリアスが効かない)
is_draw = TRUE
is_closed = FALSE # 効かない
is_fill = FALSE
is_stroke = TRUE
elif mode == 5: # 閉じるストローク(アンチエイリアスが効かない)
is_draw = TRUE
is_closed = TRUE
is_fill = FALSE
is_stroke = TRUE
#
vectors = pdb.gimp_vectors_new(image, 'path') # パス新規作成
pdb.gimp_image_add_vectors(image, vectors, 0) # パスを画像に追加
#
# パスとしてストロークを追加
#
stroke_id = pdb.gimp_vectors_stroke_new_from_points(vectors, 0,
len(points), points, is_closed)
#
# パスを表示
#
pdb.gimp_vectors_set_visible(vectors, TRUE)
#
# 描画するよう指定されてたら、パスから選択範囲を作って描画する。
#
if is_draw:
#
# 選択範囲解除
#
pdb.gimp_selection_none(image)
#
# パスから選択範囲作成
#
pdb.gimp_vectors_to_selection(
vectors,
CHANNEL_OP_REPLACE,
TRUE,
FALSE,
0,
0,
)
#
# 前景色で描画
#
drawable = pdb.gimp_image_active_drawable(image)
if is_fill:
pdb.gimp_edit_fill(drawable, FOREGROUND_FILL)
elif is_stroke:
pdb.gimp_edit_stroke(drawable)
else:
pdb.gimp_drawable_edit_stroke_item(drawable, vectors)
#
# 選択範囲解除
#
pdb.gimp_selection_none(image)
#
# パス削除が指定されていたらパスを削除する。
#
if delete_path:
# パス削除
#
pdb.gimp_image_remove_vectors(image, vectors)
#
return
def get_absolute_point(list):
""" """
rlist = []
for pos in list:
if len(pos) == 6:
(x, y, rx1, ry1, rx2, ry2) = pos
x1 = x + rx1
y1 = y + ry1
x2 = x + rx2
y2 = y + ry2
else:
(x, y) = pos
x1 = x
y1 = y
x2 = x
y2 = y
rlist.extend([
x1,
y1,
x,
y,
x2,
y2,
])
return rlist
# 絶対座標取得
def get_absolute_point2(x, y, list):
""" """
rlist = []
bx = x
by = y
for pos in list:
if len(pos) == 6:
(rx0, ry0, rx1, ry1, rx2, ry2) = pos
bx = bx + rx0
by = by + ry0
x1 = bx + rx1
y1 = by + ry1
x2 = bx + rx2
y2 = by + ry2
else:
(rx0, ry0) = pos
bx = bx + rx0
by = by + ry0
x1 = bx
y1 = by
x2 = bx
y2 = by
rlist.extend([
x1,
y1,
bx,
by,
x2,
y2,
])
return rlist
# パス作成(相対座標指定)
## パスを作成
### image : レイヤーを追加する画像データ
### points : パス座標
### mode : 0:描画しない、1:最後を閉じないストローク(初期値)、2:最後を閉じるストローク、3:塗りつぶし
### delete_path : TRUE:パスを削除する(初期値)、FALSE:パスを残す
def make_path_relative(
image,
points,
mode=1,
delete_path=TRUE,
):
""" パスを作成する。 """
new_points = get_absolute_point(points)
make_path(image, new_points, mode, delete_path)
# パス作成(座標・アンカー・制御点相対座標指定)
## パスを作成
### image : レイヤーを追加する画像データ
### x : 開始X座標
### y : 開始Y座標
### points : パス座標
### mode : 0:描画しない、1:最後を閉じないストローク(初期値)、2:最後を閉じるストローク、3:塗りつぶし
### delete_path : TRUE:パスを削除する(初期値)、FALSE:パスを残す
def make_path_relative2(
image,
x,
y,
points,
mode=1,
delete_path=TRUE,
):
""" パスを作成する。 """
new_points = get_absolute_point2(x, y, points)
make_path(image, new_points, mode, delete_path)
# メイン
def main():
set_bg_color(255, 255, 255, 1.0)
image = create_image(800, 600)
background_layer = add_layer(image, "背景")
transparent_layer = add_layer_transparent(image, "透明")
set_line_width(10)
set_antialias(TRUE)
# 値は(アンカーX, Y[, 制御開始点増分X, Y, 制御終了点増分X, Y])
#
# ほぼ円
points = [
(+100, 0, 0, -50, 0, +50),
(-100, +100, +50, 0, -50, 0),
(-100, -100, 0, +50, 0, -50),
(+100, -100, -50, 0, +50, 0),
]
# 緑円
set_color(0, 255, 0, 1.0)
make_path_relative2(image, 320, 300, points, 3, TRUE)
# 青円
set_color(0, 0, 255, 1.0)
make_path_relative2(image, 480, 300, points, 3, TRUE)
#
# 不透明部分(緑円+青円)を選択する
pdb.gimp_image_select_item(image, 0, transparent_layer)
# 選択範囲からマスクを作成する
mask = pdb.gimp_layer_create_mask(transparent_layer, ADD_SELECTION_MASK)
# マスクをレイヤーに追加する
pdb.gimp_layer_add_mask(transparent_layer, mask)
# マスク編集を無効にする(マスクでない部分を編集する)
pdb.gimp_layer_set_edit_mask(transparent_layer, FALSE)
# 赤円
set_color(255, 0, 0, 1.0)
make_path_relative2(image, 400, 230, points, 3, TRUE)
# マスクをレイヤーから削除する
pdb.gimp_layer_remove_mask(transparent_layer, MASK_APPLY)
# オレンジ円
set_color(255, 127, 0, 1.0)
make_path_relative2(image, 400, 370, points, 3, TRUE)
#
display_image(image)
main()