GIMPのPython-Fuで選択領域をスタンプで塗りつぶすプラグイン3

GIMP コンピュータ
GIMP
選択領域をスタンプで塗りつぶすプラグインを使っていて個人的に使いやすく少しカスタマイズします。

変更点

  • スタンプのブラシサイズを画素数に合わせて調整
  • レイヤーの統合フラグ。デフォルトON

スクリプト

#!/usr/bin/env python
# coding: utf8
from gimpfu import *
from array import array
from time import time
def plugin_main(image, layer, brush_size, vector, grow_step, brush_scale, enable_blur, merge_flag):
    # レイヤーの幅と高さを取得
    w = layer.width
    h = layer.height
    # ブラシサイズの調整
    if brush_size == -1:
        if w < 2000 or h < 2000:
            brush_size = 8
        elif w < 3000 or h < 3000:
            brush_size = 16
        elif w < 4000 or h < 4000:
            brush_size = 24
        else:
            brush_size = 32       
    # プログレスバー初期化
    gimp.progress_init("StampFill")
    # Undo開始
    pdb.gimp_image_undo_group_start(image)
    # 範囲選択を拡大
    pdb.gimp_selection_grow(image, grow_step)
    # 範囲選択を取得
    (non_empty,x1,y1,x2,y2) = pdb.gimp_selection_bounds(image)
    # 範囲選択されていない場合終了
    if (non_empty == 0):
        gimp.message("Not Select")
        return
    # 新しい透明レイヤーを作成
    new_layer = gimp.Layer(image, "Paint", w, h, RGB_IMAGE, 100, NORMAL_MODE)
    # レイヤーの位置を取得
    index = pdb.gimp_image_get_layer_position(image, layer)
    image.add_layer(new_layer, index)
    pdb.gimp_layer_add_alpha(new_layer)
    pdb.gimp_edit_clear(new_layer)
    new_layer.fill(TRANSPARENT_FILL)
    # ブラシのセット
    pdb.gimp_context_set_brush_size(brush_size)
    # 移動量
    step = int(brush_size * brush_scale) if brush_scale > 0.0 else int(brush_size)
    #gimp.message("step:{0}".format(step))
    try:
        if vector == "LR":
            # ループ
            for y in range(y1, y2, step):
                src_x = -1
                src_y = -1
                # 色取得ループ
                for x in range(x1, x2):
                    r = pdb.gimp_selection_value(image, x, y)
                    if (r != 0):
                        src_x = x - 1
                        src_y = y
                        break
                # クローン
                pdb.gimp_clone(new_layer, layer, 0, src_x, src_y, 4, [x1, y, x2, y])
                # プログレスバー更新
                gimp.progress_update(float(y-y1)/float(y2-y1))
        elif vector == "RL":
            # ループ
            for y in range(y1, y2, step):
                src_x = -1
                src_y = -1
                # 色取得ループ
                for x in range(x2-1, x1-1, -1):
                    r = pdb.gimp_selection_value(image, x, y)
                    if (r != 0):
                        src_x = x + 1
                        src_y = y
                        break
                # クローン
                pdb.gimp_clone(new_layer, layer, 0, src_x, src_y, 4, [x2, y, x1, y])
                # プログレスバー更新
                gimp.progress_update(float(y-y1)/float(y2-y1))
        elif vector == "UD":
            # ループ
            for x in range(x1, x2, step):
                src_x = -1
                src_y = -1
                # 色取得ループ
                for y in range(y1, y2):
                    r = pdb.gimp_selection_value(image, x, y)
                    if (r != 0):
                        src_x = x
                        src_y = y - 1
                        break
                # クローン
                pdb.gimp_clone(new_layer, layer, 0, src_x, src_y, 4, [x, y1, x, y2])
                # プログレスバー更新
                gimp.progress_update(float(x-x1)/float(x2-x1))
        elif vector == "DU":
            # ループ
            for x in range(x1, x2, step):
                src_x = -1
                src_y = -1
                # 色取得ループ
                for y in range(y2-1, y1-1, -1):
                    r = pdb.gimp_selection_value(image, x, y)
                    if (r != 0):
                        src_x = x
                        src_y = y + 1
                        break
                # クローン
                pdb.gimp_clone(new_layer, layer, 0, src_x, src_y, 4, [x, y2-1, x, y1-1])
                # プログレスバー更新
                gimp.progress_update(float(x-x1)/float(x2-x1))
        # ガウシアンフィルタ
        if enable_blur == True:
            pdb.plug_in_sel_gauss(image, image.active_drawable, 5.0, 51)
    finally:
        # Undo終了
        pdb.gimp_image_undo_group_end(image)
        # オフセット取得
        x0,y0 = pdb.gimp_drawable_offsets(new_layer)
        # レイヤーサイズの変更
        pdb.gimp_layer_resize(new_layer,x2-x1,y2-y1,x0-x1,y0-y1)
        # レイヤーの統合
        if merge_flag == True:
            name = pdb.gimp_item_get_name(layer)
            result = pdb.gimp_image_merge_down(image, new_layer, index)
            pdb.gimp_item_set_name(result, name)
        else:
            # レイヤーの更新
            layer.flush()
            layer.update(0,0,w,h)
register("StampFill", "", "", "", "", "",
    "スタンプ塗潰し", 
    "RGB*",
    [
    (PF_IMAGE, "image", "Input image", None),
    (PF_DRAWABLE, "drawable", "Drawable", None),
    (PF_INT32, "brush_size", "ブラシサイズ", -1),
    (PF_RADIO, "vector", "方向", "LR", (("左から右", "LR"), ("右から左", "RL"), ("上から下", "UD"), ("下から上", "DU"))),
    (PF_INT32, "grow_step", "領域拡大するサイズ", 2),
    (PF_FLOAT, "brush_scale", "移動量(ブラシサイズ*倍率)", 0.25),
    (PF_BOOL, "enable_blur", "ぼかし処理", True),
    (PF_BOOL, "merge_flag", "レイヤーを統合", True),
    ],
    [],
    plugin_main,
    menu = "<Image>/Filters")
main()

コメント