この記事はアドカレに参加しています。
グラデーションを考える
半年前に書いたものを載せます。
半年前の僕は文章が上手ですね。
<はじめに>
スクリプト制御でグラデーションをやっていきます。
四隅の色でやるやつです。
<コード>
local w,h=obj.getpixel()
local ColorTable={0xff8e58,0x4dd9ff,0xe5ade0,0x7eb069}
local RT,GT,BT={},{},{}
local r,g,b={},{},{}
for i=1,4 do
RT[i],GT[i],BT[i]=RGB(ColorTable[i])
end
for x=0,w do
for y=0,h do
local xw,yh=x/w,y/h
r[1]=RT[1]+(RT[2]-RT[1])*xw
r[2]=RT[3]+(RT[4]-RT[3])*xw
r[1]=r[1]+(r[2]-r[1])*yh
g[1]=GT[1]+(GT[2]-GT[1])*xw
g[2]=GT[3]+(GT[4]-GT[3])*xw
g[1]=g[1]+(g[2]-g[1])*yh
b[1]=BT[1]+(BT[2]-BT[1])*xw
b[2]=BT[3]+(BT[4]-BT[3])*xw
b[1]=b[1]+(b[2]-b[1])*yh
obj.putpixel(x,y,RGB(r[1],g[1],b[1]),1)
end
end
<断り書き>
たぶん、今回のアルゴリズムは効率が悪いです。
じゃあ、なぜ効率の良いアルゴリズムを使わないかというと、僕があまり理解できていないからです。
興味ある人は以下のサイトとかを見るといいかもしれないです。
https://talavax.com/gradationimage4.html
https://daeudaeu.com/linear/
<普通のグラデ>
まずは普通のグラデーションを考えてみます。
↓こんなかんじのものです。
これはとても単純で、
右に行くほど一つ目の色(赤)に、左に行くほど二つ目の色(青)になるようにします。
コードは以下のようになります。
local w,h=obj.getpixel()
R_1,G_1,B_1=RGB(0xff0000)
R_2,G_2,B_2=RGB(0x0000ff)
for x=0,w do
local r,g,b
r=R_1+(R_2-R_1)*x/w
g=G_1+(G_2-G_1)*x/w
b=B_1+(B_2-B_1)*x/w
for y=0,h do
obj.putpixel(x,y,RGB(r,g,b),1)
end
end
コードを少し細かく見ていきます。
まず、obj.getpixel()で縦と横のピクセル数を取得します。
次に、RGB()でカラーコードを RGB の要素に分解します。
分解して得られた RGB をもとに、一つずつピクセルの色を書き換えていきます。すべてのピクセルの色を書き換えるので、二重ループになります。
色を書き換える際には obj.putpixel()を使います。
これでグラデーションを作れました。
<四隅のグラデ>
それでは、四隅のグラデを作っていきます。
↓こんなかんじのものです。
まず、どのようになっているかを考えてみます。
色は四つあります。
角に近くなるにつれて、何かしらの色に近くなります。
真ん中らへんは四色の平均の色です。
…こんなかんじになっているのが分かると思います。
では、(x,y)の位置にあるピクセルの色を求めていきます。
それぞれの色と位置の座標をまとめてみると、以下のようになっています。
考えやすくするために、xとyに分けて考えます。
xについては、
左上と右上、左下と右下の組み合わせがあります。
どちらも、普通のグラデーションと同じように色を求めることができます。
任意のピクセルの場所を白丸として、
左上と右上、左下と右下で補間したときに、黄色丸の色を見つけたことになります。
この二つの黄色丸をさらに補間することで、任意のピクセルの色を求めれます。
<おわりに>
ピクセル操作はオブジェクトのピクセル数が多ければ多いほど重たいですが、
とても便利なものです。
一時保存系のスクリプトなどを上手く駆使することで、編集にとても役立ちます。
今回のグラデーションの場合は画像に加算合成するだけでも楽しいと思います。