レイヤーの幅と高さを取得
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
(なんか青じゃ無いような?)
レイヤーの塗りつぶし
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 ... 範囲内
コメント