Windows版GIMP3でPython-Fuを試す2。

コンピュータ

レイヤーの幅と高さを取得

w, h = layer.get_width(), layer.get_height()

Colorオブジェクトを新規作成

c = Gegl.Color.new("#00FF00") # オブジェクトを緑(00FF00)で作成
c.get_rgba()                  # RGBAを取得
# (red=0.0, green=1.0, blue=0.0, alpha=1.0)

指定座標のピクセルの色情報を読み込み

x, y = 10, 20             # 取得する座標
c = layer.get_pixel(x, y) # ピクセルの色情報を取得
c.get_rgba()              # Colorオブジェクトからrgbaを取得
# (red=1.0, green=0.0, blue=0.0, alpha=1.0)

指定座標のピクセルに色情報を書き込み

c = Gegl.Color.new("0000FF") # 青
layer.set_pixel(0, 0, c) # x.0 y.0に色をセット
# True
layer.update(0, 0, 1, 1) # 更新
# True

image
(なんか青じゃ無いような?)

レイヤーの塗りつぶし

from gi.repository import Gimp, Gegl, Babl
import time

# 画像と“先頭の選択レイヤー”を取得
img = Gimp.get_images()[0]
sel = img.get_selected_layers()
layer = sel[0] if sel else None
if not layer:
    raise RuntimeError("レイヤー未選択")

# RGB系以外だと見た目が想定と異なる可能性あり(GRAY/INDEXEDは内部で変換されます)
w, h = layer.get_width(), layer.get_height()

# ループ開始 
t0 = time.perf_counter()

# 全ピクセル走査:R を 1.0(=255)に、他は維持
for y in range(h):
    for x in range(w):
        col = layer.get_pixel(x, y) # -> Gegl.Color
        r, g, b, a = col.get_rgba()   # 0.0〜1.0 の sRGB
        col.set_rgba(1.0, g, b, a)  # R=最大、G/B/Aはそのまま
        _ = layer.set_pixel(x, y, col)

# ループ終了
t9 = time.perf_counter()

# まとめて画面更新
layer.update(0, 0, w, h)

# 処理時間
loop_ms   = (t9 - t0) * 1000
print(f"Loop: {loop_ms:.1f} ms")

# Loop: 14837.0 ms

256×256ピクセルのレイヤーの書き込みで約15秒ほど

レイヤーの塗りつぶし(高速版)

from gi.repository import Gimp, Gegl
import time

# --- 対象レイヤー ---
img = Gimp.get_images()[0]
sel = img.get_selected_layers()
layer = sel[0] if sel else None
if not layer:
    raise RuntimeError("レイヤー未選択")

w, h = layer.get_width(), layer.get_height()
if w == 0 or h == 0:
    raise RuntimeError("レイヤーサイズが 0")

buf  = layer.get_buffer()
rect = Gegl.Rectangle.new(0, 0, w, h)

# 1) 読み出しフォーマットを決める(まず RGBA8 を試し、無理なら RGB8)
FMT_CANDIDATES = ["R'G'B'A u8", "RGBA u8", "R'G'B' u8", "RGB u8"]
for FMT in FMT_CANDIDATES:
    raw = bytearray(buf.get(rect, 1.0, FMT, Gegl.AbyssPolicy.NONE))
    px = w * h
    if len(raw) in (px*4, px*3):
        break
else:
    raise RuntimeError(f"想定外の配列長 len={len(raw)} for {w}x{h}")

BPP = len(raw) // (w*h)   # 3 or 4

# -- loop: 読み込み済み raw を編集 → 書き戻し --
t0 = time.perf_counter()

for y in range(h):
    row_base = y * w * BPP
    for x in range(w):
        i = row_base + x * BPP
        raw[i + 0] = 255  # R
        raw[i + 1] = 0    # G
        raw[i + 2] = 0    # B
        if BPP == 4:
            raw[i + 3] = 255  # A

buf.set(rect, FMT, bytes(raw))

t1 = time.perf_counter()
# -- end loop --

layer.update(0, 0, w, h)

print(f"Loop: {(t1 - t0)*1000:.1f} ms")

# Loop: 61.6 ms

1秒以下になりました。ちょっと速すぎる気がする。

選択範囲バウンディングボックスを取得する。

Gimp.Selection.bounds(img)
# (True, non_empty=True, x1=862, y1=44, x2=1076, y2=342)

True … 関数の成功
non_empy…Ttrue 範囲選択されている。False 範囲選択されていない
x1…862 バウンディングボックスの左上隅のx座標
y1…44 バウンディングボックスの左上隅のy座標
x2…1076 バウンディングボックスの右下隅のx座標
y2…342 バウンディングボックスの右下隅のy座標

座標が選択範囲内か判定

Gimp.Selection.value(img, x, y)
# 0 ... 範囲外
# 255 ... 範囲内

コメント