DXライブラリで画像の輝度を変更


DXライブラリでの画像加工その2。左右キーで画像の明るさを自由に変更できるようにします。

所要時間は5分くらいです。

 

スポンサードリンク

前置き

DXライブラリを用いて画像加工ソフトを作成していきます。初期設定はこちらからどうぞ。また、ページ下にコード全てを張っておくので、わけわかめになったらそちらもご覧ください。

今回の実行用素材は、下のフリーのものをお借りしました。すっかり夏であります。


*クリックで拡大

前回同様画像名はtest、サイズは 640×480 、形式は bmp です。

 

キーボードの入力受取

前回までのプログラムではキー入力を監視する関数を追加していなかったので、まずはそちらから。こちらのページのように、GetKey関数を追加します。

int ky[256];
int GetKey(){
	char KEY[256];
	GetHitKeyStateAll(KEY);
	for(int i=0;i<256;i++){ 
		if(KEY[i]!=0)ky[i]++;
		else ky[i]=0;
	}
	return 0;
}

また、メインループの条件部にGetKeyの監視を追加します。

while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && GetKey()==0){/**/}

これで準備は完了。キー入力に対応して処理をしたいときは、

if(ky[KEY_INPUT_LEFT]>=1){/**/}
if(ky[KEY_INPUT_RIGHT]>=1){/**/}

↑のような形で書けばOKであります。

 

スポンサードリンク

輝度変更機能の追加

それでは早速、変更機能を作成していきます。左キー押時に輝度を下げる、右キー押時に輝度を上げるようにしていきたいと思います。

if(ky[KEY_INPUT_RIGHT]>=1){
	for(int x=0;x<640;x++){
		for(int y=0;y<480;y++){
			for(int i=0;i<3;i++){
				Cr[x][y][i]++;
			}
		}
	}
}

これをメインループ下に貼り付け。前回作成した、色情報を格納する配列Crの値を増やしていきます。640(x軸分)×480(y軸分)×3(RGBの3色分)、合計で100万回近いループになりますね。パソコンすげえ。左キーによる輝度下げも、Crの値を減らしていけば作成できます。実行した結果は以下のように。


*クリックで拡大

↓右キー5秒くらい。


*クリックで拡大

悲劇的ビフォーアフター。突然の世紀末。これはひどい。一周回って芸術。

台無しにした要因は、色配列Crの値が 0~255 を超えてしまったことにあります。絵を描写している関数 DrawPixel は、これらに収まる値になるようにCrの値を独自解釈(おそらくCr%256)してしまうため、このような残念加工となりました。これはこれでありの気がしないでもない。

修正用に、メイン描写の部分にひと手間加えます。Crの値が255より上、もしくは0未満の時に特別処理を行うようにしましょう。

for(int x=0;x<640;x++){
	for(int y=0;y<480;y++){
		for(int i=0;i<3;i++){ if(Cr[x][y][i]>255)c[i]=255;
			else if(Cr[x][y][i]<0)c[i]=0;
			else c[i]=Cr[x][y][i];
		}
		DrawPixel(x,y,GetColor(c[0],c[1],c[2]));
	}
}

このように変更して実行した結果は以下の形です。


*クリックで拡大


*クリックで拡大

今度は無事に輝度の変更ができました。やったぜ。

ここまでのプログラム全体は以下のとおり。

#include "DxLib.h"
int Cr[640][480][4];
int ky[256];
int GetKey(){
	char KEY[256];
	GetHitKeyStateAll(KEY);
	for(int i=0;i<256;i++){
		if(KEY[i]!=0)ky[i]++;
		else ky[i]=0;
	}
	return 0;
}
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );
	SetMainWindowText("graph");
	DxLib_Init();
	int c[3];
	int handle=LoadSoftImage("test.bmp");
	for(int x=0;x<640;x++){
		for(int y=0;y<480;y++){
			GetPixelSoftImage(handle,x,y,&Cr[x][y][0],&Cr[x][y][1],&Cr[x][y][2],&Cr[x][y][3]);
		}
	}
	DeleteSoftImage(handle);
	while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && GetKey()==0){
		//明るく
		if(ky[KEY_INPUT_RIGHT]>=1){
			for(int x=0;x<640;x++){
				for(int y=0;y<480;y++){
					for(int i=0;i<3;i++){
						Cr[x][y][i]++;
					}
				}
			}
		}
		//暗く
		if(ky[KEY_INPUT_LEFT]>=1){
			for(int x=0;x<640;x++){
				for(int y=0;y<480;y++){
					for(int i=0;i<3;i++){
						Cr[x][y][i]--;
					}
				}
			}
		}
		//描写
		for(int x=0;x<640;x++){
			for(int y=0;y<480;y++){
				for(int i=0;i<3;i++){
					if(Cr[x][y][i]>255)c[i]=255;
					else if(Cr[x][y][i]<0)c[i]=0;
					else c[i]=Cr[x][y][i];
				}
				DrawPixel(x,y,GetColor(c[0],c[1],c[2]));
			}
		}
	}
	DxLib_End();
	return 0;
}
スポンサードリンク