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

コンピュータ

前回のスクリプトからの変更点
・方向ごとにスクリプトが4つに分かれていましたが一つにまとめました。
・Ctrl-ZでUndoに対応しました。
・各種パラメタを変更するGUI。
・進捗プログレスバー。
・塗りつぶし領域を別レイヤーにしました。

#!/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):
    # レイヤーの幅と高さを取得
    w = layer.width
    h = layer.height
    # プログレスバー初期化
    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)
        # レイヤーの更新
        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", "ブラシサイズ", 32),
    (PF_RADIO, "vector", "方向", "LR", (("左から右", "LR"), ("右から左", "RL"), ("上から下", "UD"), ("下から上", "DU"))),
    (PF_INT32, "grow_step", "領域拡大するサイズ", 2),
    (PF_FLOAT, "brush_scale", "移動量(ブラシサイズ*倍率)", 0.25),
    (PF_BOOL, "enable_blur", "ぼかし処理", True),
    ],
    [],
    plugin_main,
    menu = "<Image>/Filters")
main()

コメント