ピクセル操作

入力画像を 1 ピクセルずつ読み書きできます。色の反転・グレースケール・ビネットなど、 座標や色に基づく加工はピクセル操作で実現します。

座標と色の約束

ピクセル操作は実際の入力画像へアクセスするため、初回アクセス時に画像データの転送が発生します。 転送は最初の 1 回だけです。

getpixel / setpixel

関数戻り値説明
obj.getpixel(x, y)r, g, b, a指定座標の色を取得(各成分 0 ~ 255)
obj.setpixel(x, y, r, g, b [, a])なし指定座標へ書き込み(a 既定 255)

赤成分を反転する

for y = 0, obj.h - 1 do
    for x = 0, obj.w - 1 do
        local r, g, b, a = obj.getpixel(x, y)
        obj.setpixel(x, y, 255 - r, g, b, a)
    end
end

getpixeldata — 直接アクセス(高速)

obj.getpixeldata() は、全ピクセルへ直接アクセスできるプロキシを返します。 1 ピクセルずつ関数を呼ぶ getpixel / setpixel より高速です。

メンバー説明
pd.width / pd.height画像の幅 / 高さ
pd:get(index)指定インデックスのチャンネル値を取得(0 ~ 255)
pd:set(index, value)指定インデックスのチャンネル値を設定(0 ~ 255 にクランプ)

インデックスは 1 始まりで、各ピクセルにつき R, G, B, A の 4 チャンネルが順に並びます。 座標 (x, y) の R チャンネルのインデックスは (y * pd.width + x) * 4 + 1 です。 続く +1, +2, +3 がそれぞれ G, B, A になります。

プロキシのメンバーアクセスはコロン記法(pd:get(i) / pd:set(i, v))で呼びます。 幅・高さはドット記法(pd.width / pd.height)で読みます。

グレースケール化

local pd = obj.getpixeldata()
local w = pd.width
local h = pd.height
for y = 0, h - 1 do
    for x = 0, w - 1 do
        local base = (y * w + x) * 4
        local r = pd:get(base + 1)
        local g = pd:get(base + 2)
        local b = pd:get(base + 3)
        local gray = r * 0.299 + g * 0.587 + b * 0.114
        pd:set(base + 1, gray)
        pd:set(base + 2, gray)
        pd:set(base + 3, gray)
    end
end

中心からの距離でフェード(円形ビネット)

local pd = obj.getpixeldata()
local w = pd.width
local h = pd.height
local cx = w / 2
local cy = h / 2
local maxd = anim.len(cx, cy)
for y = 0, h - 1 do
    for x = 0, w - 1 do
        local base = (y * w + x) * 4
        local d = anim.len(x - cx, y - cy)
        local k = anim.clamp(1 - d / maxd, 0, 1)
        pd:set(base + 4, pd:get(base + 4) * k)
    end
end

アルファの扱い

A チャンネル(インデックス base + 4)を変更すると、不透明度が変わります。 このとき RGB はストレートな色味を保ったまま再計算されます。アルファを 0 にすると、そのピクセルは透明になります。

putpixeldata について

obj.putpixeldata() は AviUtl との互換のために存在します。このプラグインでは、 次の読み出しやスクリプトの終わりで変更が自動的に反映されるため、呼び出す必要はありません。 呼び出したときは、その時点で未反映の変更をまとめて反映します。

性能とエンジン

ピクセル処理は重くなりがちです。このプラグインは getpixel / setpixel を含むスクリプトを、 利用できる環境では自動的に高速なネイティブレーンへ振り分けます。さらに、二重ループで getpixel → 計算 → setpixel という決まった形のスクリプトや、 getpixeldata のハンドルを基底インデックスで読み書きする決まった形のスクリプトは、 CPU カーネルや GPU カーネルへ変換してさらに高速に実行します。GPU カーネルは初回に CPU カーネルとの一致を検証したうえで自動選択します。 詳しくは エンジンと高速化 を参照してください。

← scene と ymm4 エンジンと高速化 →