お恥ずかしながらHSPコンテストに公開したセピアフィルターについて解説したくなったので、勝手にしていきたいと思います。
まずセピア色とは、イカ墨で描かれた茶色っぽい色のことです。
写真などを古く見せたい場合などは、カラー写真をわざとセピア調に変換したりしますよね。
で、プログラムはどうなってるかというとまず1ドットずつR、G、Bを取得しその数値をY、U、Vという形に変換します。そしてU=-23.296 、V=14.336 としてまたR、G、Bの形に変換してスクリーンに反映させます。
ここで、一応補足ですがR、G、B、Y、U、Vは全部変数で、Rにも0~255の整数が、Gにも0~255が、Bにも0~255が、Yにも0~255、Uには-128~127が、Vにも-128~127が・・・とそれぞれ6つの変数全部が256通りの色の情報を持っています。(24bitフルカラーの場合)
下にRGB→YUVの変換式(回転行列)とその逆行列YUV→RGBを載せました↓
図では行列が描いてありますが、プログラムではちゃんと計算式に展開しないといけません(少なくともHSPの場合)。
これをすべてのドットで行うと、どんな画像でもちゃんとお望みのセピアになっているはずです!
例えばHSP言語で書くとどうなるか
横30縦20ドットで
1のバッファに変換前2のバッファに変換後の画像が出力されるようなプログラムで行きたいと思います
reepat 20
a=cnt
reepat 30
gsel 1
pget cnt,a:r=ginfo_r:g=ginfo_g:b=ginfo_b ; RGB値を取得し代入
y=0.299*r+0.587*g+0.114*b ; 行列の計算1
u=-0.169*r-0.331*g+0.5*b ; 行列の計算2
v=0.5*r-0.419*g-0.081*b ; 行列の計算3
u=-23.296:v=14.336
r=1.0*y+1.402*v ; 逆行列の計算1
g=1.0*y-0.334*u-0.714*v ; 逆行列の計算2
b=1.0*y+1.772*u ; 逆行列の計算3
gsel 2
color r,g,b
pset cnt,a
loop
loop
以上です。
そのままコピペして実行してもエラーになります(バッファの確保は各自でお願いします)
さて今のままでは計算時間が膨大になり非効率なので、次回は↑の変換アルゴリズムをどんどん簡略化していきますよー!
無駄な計算を省いていくと、最後にある発見をします。