コンボリュート法による画像処理色々

解説

 3行3列のパラメータを利用したコンボリュート法による画像処理例。
 この方法を使うとぼかし、シャープ、エンボス、輪郭検出...さまざまな 処理を行える。とは言うものの単純にコンボリュートを施しただけでは暗すぎ て(コントラストがなさすぎて)思ったように結果が見えなかったりもする。 そのため実際にこれらの方法を使って画像処理をする場合は、ほかの画像処理 法と組み合わせて使った方がいい。
 ここに挙げたパラメータはほんの一例にすぎないが、それでも単に行列を回 転させただけのものも多い(つまり重複しているものも多い)。


実行例

 次に挙げる画像は上から順に以下のパラメータ指定による実行結果。
		case	CONV_EMBOSS01:
			//エンボス処理パラメータ1
			pnOperate[0] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[1] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[2] = 0;			//[  0 ][  0 ][ -8 ]
			pnOperate[3] = 0;
			pnOperate[4] = 1;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = -1;
			break;

		case	CONV_EMBOSS02:
			//エンボス処理パラメータ2
			pnOperate[0] = 2;			//[  2 ][  0 ][  0 ]
			pnOperate[1] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[2] = 0;			//[  0 ][  0 ][ -1 ]
			pnOperate[3] = 0;
			pnOperate[4] = -1;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = -1;
			break;

		case	CONV_EMBOSS03:
			//エンボス処理パラメータ3
			pnOperate[0] = -2;			//[ -2 ][ -1 ][  0 ]
			pnOperate[1] = -1;			//[ -1 ][  1 ][  1 ]
			pnOperate[2] = 0;			//[  0 ][  1 ][  2 ]
			pnOperate[3] = -1;
			pnOperate[4] = 1;
			pnOperate[5] = 1;
			pnOperate[6] = 0;
			pnOperate[7] = 1;
			pnOperate[8] = 2;
			break;

		case	CONV_EMBOSS04:
			//エンボス処理パラメータ4Laplascian
			pnOperate[0] = -1;			//[ -1 ][  0 ][ -1 ]
			pnOperate[1] = 0;			//[  0 ][  4 ][  0 ]
			pnOperate[2] = -1;			//[ -1 ][  0 ][ -1 ]
			pnOperate[3] = 0;
			pnOperate[4] = 4;
			pnOperate[5] = 0;
			pnOperate[6] = -1;
			pnOperate[7] = 0;
			pnOperate[8] = -1;
			break;

		case	CONV_EMBOSS05:
			//エンボス処理パラメータ5全方向
			pnOperate[0] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[1] = -1;			//[ -1 ][  8 ][ -1 ]
			pnOperate[2] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[3] = -1;
			pnOperate[4] = 8;
			pnOperate[5] = -1;
			pnOperate[6] = -1;
			pnOperate[7] = -1;
			pnOperate[8] = -1;
			break;



 次に挙げる画像は上から順に以下のパラメータ指定による実行結果。
		case	CONV_EMBOSS06:
			//エンボス処理パラメータ6水平方向
			pnOperate[0] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[1] = 0;			//[ -1 ][  2 ][ -1 ]
			pnOperate[2] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[3] = -1;
			pnOperate[4] = 2;
			pnOperate[5] = -1;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = 0;
			break;

		case	CONV_EMBOSS07:
			//エンボス処理パラメータ7垂直方向
			pnOperate[0] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[1] = -1;			//[  0 ][  2 ][  0 ]
			pnOperate[2] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[3] = 0;
			pnOperate[4] = 0;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = -1;
			pnOperate[8] = 0;
			break;

		case	CONV_EMBOSS08:
			//エンボス処理パラメータ8水平垂直
			pnOperate[0] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[1] = -1;			//[ -1 ][  4 ][ -1 ]
			pnOperate[2] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[3] = -1;
			pnOperate[4] = 4;
			pnOperate[5] = -1;
			pnOperate[6] = 0;
			pnOperate[7] = -1;
			pnOperate[8] = 0;
			break;

		case	CONV_EMBOSS09:
			//エンボス処理パラメータ9Lossy
			pnOperate[0] = 1;			//[  1 ][ -2 ][  1 ]
			pnOperate[1] = -2;			//[  1 ][ -2 ][  4 ]
			pnOperate[2] = 1;			//[ -2 ][ -1 ][ -2 ]
			pnOperate[3] = -2;
			pnOperate[4] = 4;
			pnOperate[5] = -2;
			pnOperate[6] = -2;
			pnOperate[7] = -1;
			pnOperate[8] = -2;
			break;

		case	CONV_EMBOSS10:
			//エンボス処理パラメータ10
			pnOperate[0] = -4;			//[ -4 ][ -2 ][  0 ]
			pnOperate[1] = -2;			//[ -2 ][  2 ][  2 ]
			pnOperate[2] = 0;			//[  0 ][  2 ][  4 ]
			pnOperate[3] = -2;
			pnOperate[4] = 2;
			pnOperate[5] = 2;
			pnOperate[6] = 0;
			pnOperate[7] = 2;
			pnOperate[8] = 4;
			break;



 次に挙げる画像は上から順に以下のパラメータ指定による実行結果。
		case	CONV_SOBEL01:
			//Sobel処理パラメータ水平
			pnOperate[0] = 1;			//[  1 ][  2 ][  1 ]
			pnOperate[1] = 2;			//[  0 ][  0 ][  0 ]
			pnOperate[2] = 1;			//[ -1 ][ -2 ][ -1 ]
			pnOperate[3] = 0;
			pnOperate[4] = 0;
			pnOperate[5] = 0;
			pnOperate[6] = -1;
			pnOperate[7] = -2;
			pnOperate[8] = -1;
			break;

		case	CONV_SOBEL02:
			//Sobel処理パラメータ垂直
			pnOperate[0] = 1;			//[  1 ][  0 ][ -1 ]
			pnOperate[1] = 0;			//[  2 ][  0 ][ -2 ]
			pnOperate[2] = -1;			//[  1 ][  0 ][ -1 ]
			pnOperate[3] = 2;
			pnOperate[4] = 0;
			pnOperate[5] = -2;
			pnOperate[6] = 1;
			pnOperate[7] = 0;
			pnOperate[8] = -1;
			break;

		case	CONV_PREWITT01:
			//Prewitt処理パラメータ水平
			pnOperate[0] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[1] = 1;			//[  0 ][  0 ][  0 ]
			pnOperate[2] = 1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[3] = 0;
			pnOperate[4] = 0;
			pnOperate[5] = 0;
			pnOperate[6] = -1;
			pnOperate[7] = -1;
			pnOperate[8] = -1;
			break;

		case	CONV_PREWITT02:
			//Prewitt処理パラメータ垂直
			pnOperate[0] = 1;			//[  1 ][  0 ][ -1 ]
			pnOperate[1] = 0;			//[  1 ][  0 ][ -1 ]
			pnOperate[2] = -1;			//[  1 ][  0 ][ -1 ]
			pnOperate[3] = 1;
			pnOperate[4] = 0;
			pnOperate[5] = -1;
			pnOperate[6] = 1;
			pnOperate[7] = 0;
			pnOperate[8] = -1;
			break;

		case	CONV_KIRSH01:
			//Kirsh処理パラメータ水平
			pnOperate[0] = 5;			//[  5 ][  5 ][  5 ]
			pnOperate[1] = 5;			//[ -3 ][ -3 ][ -3 ]
			pnOperate[2] = 5;			//[ -3 ][ -3 ][ -3 ]
			pnOperate[3] = -3;
			pnOperate[4] = -3;
			pnOperate[5] = -3;
			pnOperate[6] = -3;
			pnOperate[7] = -3;
			pnOperate[8] = -3;
			break;



 次に挙げる画像は上から順に以下のパラメータ指定による実行結果。
		case	CONV_KIRSH02:
			//Kirsh処理パラメータ垂直
			pnOperate[0] = 5;			//[  5 ][ -3 ][ -3 ]
			pnOperate[1] = -3;			//[  5 ][ -3 ][ -3 ]
			pnOperate[2] = -3;			//[  5 ][ -3 ][ -3 ]
			pnOperate[3] = 5;
			pnOperate[4] = -3;
			pnOperate[5] = -3;
			pnOperate[6] = 5;
			pnOperate[7] = -3;
			pnOperate[8] = -3;
			break;

		case	CONV_EDGE01:
			//エッジ検出処理パラメータ1
			pnOperate[0] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[1] = 1;			//[  1 ][ -4 ][  1 ]
			pnOperate[2] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[3] = 1;
			pnOperate[4] = -4;
			pnOperate[5] = 1;
			pnOperate[6] = 0;
			pnOperate[7] = 1;
			pnOperate[8] = 0;
			break;

		case	CONV_EDGE02:
			//エッジ検出処理パラメータ2
			pnOperate[0] = -5;			//[ -5 ][  0 ][  0 ]
			pnOperate[1] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[2] = 0;			//[  0 ][  0 ][ -5 ]
			pnOperate[3] = 0;
			pnOperate[4] = 0;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = -5;
			break;

		case	CONV_EDGE03:
			//エッジ検出処理パラメータ3
			pnOperate[0] = -125;		//[ -125 ][ -125 ][ -125 ]
			pnOperate[1] = -125;		//[ -125 ][ 1000 ][ -125 ]
			pnOperate[2] = -125;		//[ -125 ][ -125 ][ -125 ]
			pnOperate[3] = -125;
			pnOperate[4] = 1000;
			pnOperate[5] = -125;
			pnOperate[6] = -125;
			pnOperate[7] = -125;
			pnOperate[8] = -125;
			break;

		case	CONV_EDGE04:
			//エッジ検出処理パラメータ4
			pnOperate[0] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[1] = -1;			//[ -1 ][  8 ][ -1 ]
			pnOperate[2] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[3] = -1;
			pnOperate[4] = 8;
			pnOperate[5] = -1;
			pnOperate[6] = -1;
			pnOperate[7] = -1;
			pnOperate[8] = -1;



 次に挙げる画像は上から順に以下のパラメータ指定による実行結果。
		case	CONV_EDGE05:
			//エッジ検出処理パラメータ5
			pnOperate[0] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[1] = -1;			//[  2 ][  2 ][  2 ]
			pnOperate[2] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[3] = 2;
			pnOperate[4] = 2;
			pnOperate[5] = 2;
			pnOperate[6] = -1;
			pnOperate[7] = -1;
			pnOperate[8] = -1;
			break;

		case	CONV_EDGE06:
			//エッジ検出処理パラメータ6
			pnOperate[0] = -5;			//[ -5 ][ -5 ][ -5 ]
			pnOperate[1] = -5;			//[ -5 ][ 39 ][ -5 ]
			pnOperate[2] = -5;			//[ -5 ][ -5 ][ -5 ]
			pnOperate[3] = -5;
			pnOperate[4] = 39;
			pnOperate[5] = -5;
			pnOperate[6] = -5;
			pnOperate[7] = -5;
			pnOperate[8] = -5;
			break;

		case	CONV_EDGE07:
			//エッジ検出処理パラメータ7
			pnOperate[0] = 0;			//[  0 ][  2 ][  0 ]
			pnOperate[1] = 0;			//[  2 ][ -8 ][  2 ]
			pnOperate[2] = 0;			//[  0 ][  2 ][  0 ]
			pnOperate[3] = -1;
			pnOperate[4] = 1;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = 0;
			break;

		case	CONV_EDGEENHANCE01:
			//エッジ強調処理パラメータ
			pnOperate[0] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[1] = 0;			//[ -1 ][  1 ][  0 ]
			pnOperate[2] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[3] = -1;
			pnOperate[4] = 1;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = 0;
			break;

		case	CONV_AVRREMOVE01:
			//平均削除処理パラメータ
			pnOperate[0] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[1] = -1;			//[ -1 ][  9 ][ -1 ]
			pnOperate[2] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[3] = -1;
			pnOperate[4] = 9;
			pnOperate[5] = -1;
			pnOperate[6] = -1;
			pnOperate[7] = -1;
			pnOperate[8] = -1;
			break;



 次に挙げる画像は上から順に以下のパラメータ指定による実行結果。
		case	CONV_SHARP01:
			//シャープ処理パラメータ1
			pnOperate[0] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[1] = -1;			//[ -1 ][ 16 ][ -1 ]
			pnOperate[2] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[3] = -1;
			pnOperate[4] = 16;
			pnOperate[5] = -1;
			pnOperate[6] = -1;
			pnOperate[7] = -1;
			pnOperate[8] = -1;
			break;

		case	CONV_SHARP02:
			//シャープ処理パラメータ2
			pnOperate[0] = 0;			//[  0 ][ -2 ][  0 ]
			pnOperate[1] = -2;			//[ -2 ][ 11 ][ -2 ]
			pnOperate[2] = 0;			//[  0 ][ -2 ][  0 ]
			pnOperate[3] = -2;
			pnOperate[4] = 11;
			pnOperate[5] = -2;
			pnOperate[6] = 0;
			pnOperate[7] = -2;
			pnOperate[8] = 0;
			break;

		case	CONV_SHARP03:
			//シャープ処理パラメータ3
			pnOperate[0] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[1] = -1;			//[ -1 ][  5 ][ -1 ]
			pnOperate[2] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[3] = -1;
			pnOperate[4] = 5;
			pnOperate[5] = -1;
			pnOperate[6] = 0;
			pnOperate[7] = -1;
			pnOperate[8] = 0;
			break;

		case	CONV_SHARP04:
			//シャープ処理パラメータ4
			pnOperate[0] = 0;			//[  0 ][ -3 ][  0 ]
			pnOperate[1] = -3;			//[ -3 ][ 24 ][ -3 ]
			pnOperate[2] = 0;			//[  0 ][ -3 ][  0 ]
			pnOperate[3] = -3;
			pnOperate[4] = 24;
			pnOperate[5] = -3;
			pnOperate[6] = 0;
			pnOperate[7] = -3;
			pnOperate[8] = 0;
			break;

		case	CONV_SOFT01:
			//Gaussian blur処理パラメータ
			pnOperate[0] = 1;			//[  1 ][  2 ][  1 ]
			pnOperate[1] = 2;			//[  2 ][  4 ][  2 ]
			pnOperate[2] = 1;			//[  1 ][  2 ][  1 ]
			pnOperate[3] = 2;
			pnOperate[4] = 4;
			pnOperate[5] = 2;
			pnOperate[6] = 1;
			pnOperate[7] = 2;
			pnOperate[8] = 1;
			break;



 次に挙げる画像は上から順に以下のパラメータ指定による実行結果。
		case	CONV_SOFT02:
			//Gaussian blur処理パラメータ
			pnOperate[0] = 45;			//[  45 ][ 122 ][  45 ]
			pnOperate[1] = 122;			//[ 122 ][ 322 ][ 122 ]
			pnOperate[2] = 45;			//[  45 ][ 122 ][  45 ]
			pnOperate[3] = 122;
			pnOperate[4] = 322;
			pnOperate[5] = 122;
			pnOperate[6] = 45;
			pnOperate[7] = 122;
			pnOperate[8] = 45;
			break;

		case	CONV_SOFT03:
			//Gaussian blur処理パラメータ
			pnOperate[0] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[1] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[2] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[3] = 1;
			pnOperate[4] = 1;
			pnOperate[5] = 1;
			pnOperate[6] = 0;
			pnOperate[7] = 1;
			pnOperate[8] = 0;
			break;

		case	CONV_SOFT04:
			//ぼかし処理パラメータ
			pnOperate[0] = 1;			//[  1 ][  2 ][  1 ]
			pnOperate[1] = 2;			//[  2 ][  3 ][  2 ]
			pnOperate[2] = 1;			//[  1 ][  2 ][  1 ]
			pnOperate[3] = 2;
			pnOperate[4] = 3;
			pnOperate[5] = 2;
			pnOperate[6] = 1;
			pnOperate[7] = 2;
			pnOperate[8] = 1;
			break;

		case	CONV_SOFT05:
			//ぼかし処理パラメータ
			pnOperate[0] = 625;			//[  625 ][ 1250 ][  625 ]
			pnOperate[1] = 1250;		//[ 1250 ][ 2500 ][ 1250 ]
			pnOperate[2] = 625;			//[  625 ][ 1250 ][  625 ]
			pnOperate[3] = 1250;
			pnOperate[4] = 2500;
			pnOperate[5] = 1250;
			pnOperate[6] = 625;
			pnOperate[7] = 1250;
			pnOperate[8] = 625;
			break;

		case	CONV_SOFT06:
			//ぼかし処理パラメータ
			pnOperate[0] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[1] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[2] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[3] = 1;
			pnOperate[4] = 1;
			pnOperate[5] = 1;
			pnOperate[6] = 1;
			pnOperate[7] = 1;
			pnOperate[8] = 1;
			break;



 次に挙げる画像は上から順に以下のパラメータ指定による実行結果。
		case	CONV_SOFT07:
			//ぼかし処理パラメータ
			pnOperate[0] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[1] = 1;			//[  1 ][  0 ][  1 ]
			pnOperate[2] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[3] = 1;
			pnOperate[4] = 0;
			pnOperate[5] = 1;
			pnOperate[6] = 0;
			pnOperate[7] = 1;
			pnOperate[8] = 0;
			break;

		case	CONV_SOFT08:
			//ぼかし処理パラメータ
			pnOperate[0] = 2;			//[  2 ][  2 ][  2 ]
			pnOperate[1] = 2;			//[  2 ][  1 ][  2 ]
			pnOperate[2] = 2;			//[  2 ][  2 ][  2 ]
			pnOperate[3] = 2;
			pnOperate[4] = 1;
			pnOperate[5] = 2;
			pnOperate[6] = 2;
			pnOperate[7] = 2;
			pnOperate[8] = 2;
			break;

		case	CONV_LAPLACIAN01:
			//ラプラシアン処理パラメータ全方向
			pnOperate[0] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[1] = 1;			//[  1 ][ -8 ][  1 ]
			pnOperate[2] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[3] = 1;
			pnOperate[4] = -8;
			pnOperate[5] = 1;
			pnOperate[6] = 1;
			pnOperate[7] = 1;
			pnOperate[8] = 1;
			break;

		case	CONV_LAPLACIAN02:
			//ラプラシアン処理パラメータ上下左右
			pnOperate[0] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[1] = 1;			//[  1 ][ -4 ][  1 ]
			pnOperate[2] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[3] = 1;
			pnOperate[4] = -4;
			pnOperate[5] = 1;
			pnOperate[6] = 0;
			pnOperate[7] = 1;
			pnOperate[8] = 0;
			break;



ソースコード

 WTLのプロジェクトウイザードを使ってSDI Apllicationプロジェクトを作成し、View用の ヘッダーファイルを以下のように変える。ここではプロジェクト名を「ImageEffect110」と しています。

// ImageEffect110View.h : interface of the CImageEffect110View class
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

#include 
#pragma	comment(lib,"Gdiplus.lib")


class CImageEffect110View : public CWindowImpl
{
public:
	DECLARE_WND_CLASS(NULL)

	BOOL PreTranslateMessage(MSG* pMsg)
	{
		pMsg;
		return FALSE;
	}

	BEGIN_MSG_MAP(CImageEffect110View)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
	END_MSG_MAP()

// Handler prototypes (uncomment arguments if needed):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)



	//
	//コンボリューション処理
	//
	//nWidthは画像の幅(単位ピクセル)
	//nHeightは画像の高さ(単位ピクセル)
	//nStrideBytesは画像の幅一列あたりのサイズ(単位bytes)
	//pRgbDataは画像データ(RGBTRIPLEの並び)
	//pnOperateは処理行列(3行3列)
	//bNotDivideは積算後に除算を行わないか、行うかの指定(falseなら除算する)
	//
	bool	Convolution(ULONG nWidth,ULONG nHeight,long nStrideBytes,BYTE* pRgbData,int pnOperate[9],bool bNotDivide=false)
	{
		int			i;
		ULONG		x;
		ULONG		y;
		long		nTmpR;
		long		nTmpG;
		long		nTmpB;
		int			nDiv;			//計算結果を除算する値 = pnOperate[]の合計値
		long		nPosBytes;
		BYTE*		pNew;			//新しい色値の画像を入れるバイト配列
		RGBTRIPLE*	pRgbUp;			//左上の元値のピクセル(+1で上、+2で右上)
		RGBTRIPLE*	pRgbCur;		//左の元値のピクセル(+1で中心、+2で右)
		RGBTRIPLE*	pRgbDown;		//左下の元値のピクセル(+1で下、+2で右下)
		RGBTRIPLE*	pRgbNew;		//新しい色値を代入するピクセル
		RGBTRIPLE*	ppRefPos[9];	//元値の上下左右斜め全9ピクセル位置

		if(bNotDivide)
			nDiv = 1;
		else
		{
			nDiv = 0;
			for(i = 0; i < 9; i++)
				nDiv += pnOperate[i];
			if(nDiv < 0)
				nDiv *= -1;
			if(nDiv == 0)
				nDiv = 1;
		}

		pNew = new BYTE[nStrideBytes * nHeight];
		for(y = 1; y < nHeight - 1; y++)
		{
			nPosBytes = (y - 1) * nStrideBytes;
			pRgbUp = (RGBTRIPLE*)&(pRgbData[nPosBytes]);

			nPosBytes += nStrideBytes;
			pRgbCur = (RGBTRIPLE*)&(pRgbData[nPosBytes]);
			pRgbNew = (RGBTRIPLE*)&(pNew[nPosBytes]);

			nPosBytes += nStrideBytes;
			pRgbDown = (RGBTRIPLE*)&(pRgbData[nPosBytes]);

			for(x = 1; x < nWidth - 1; x++)
			{
				//あるピクセルの上下左右のピクセルポインタ
				ppRefPos[0] = pRgbUp;
				ppRefPos[1] = pRgbUp + 1;
				ppRefPos[2] = pRgbUp + 2;
				ppRefPos[3] = pRgbCur;
				ppRefPos[4] = pRgbCur + 1;
				ppRefPos[5] = pRgbCur + 2;
				ppRefPos[6] = pRgbDown;
				ppRefPos[7] = pRgbDown + 1;
				ppRefPos[8] = pRgbDown + 2;

				//テーブルの値を使って計算
				nTmpR = 0;
				nTmpG = 0;
				nTmpB = 0;
				for(i = 0; i < 9; i++)
				{
					if(pnOperate[i] == 0)
						continue;

					nTmpR += ppRefPos[i]->rgbtRed		* pnOperate[i];
					nTmpG += ppRefPos[i]->rgbtGreen	* pnOperate[i];
					nTmpB += ppRefPos[i]->rgbtBlue	* pnOperate[i];
				}
				//平均値を求めるために除算
				if(nDiv != 1)
				{
					nTmpR /= nDiv;
					nTmpG /= nDiv;
					nTmpB /= nDiv;
				}

				//色ビット数を超えないように制限
				nTmpR = (nTmpR < 0) ? 0 : nTmpR;
				nTmpR = (nTmpR > 255) ? 255 : nTmpR;
				nTmpG = (nTmpG < 0) ? 0 : nTmpG;
				nTmpG = (nTmpG > 255) ? 255 : nTmpG;
				nTmpB = (nTmpB < 0) ? 0 : nTmpB;
				nTmpB = (nTmpB > 255) ? 255 : nTmpB;

				pRgbNew->rgbtBlue	= (BYTE)nTmpB;
				pRgbNew->rgbtGreen	= (BYTE)nTmpG;
				pRgbNew->rgbtRed	= (BYTE)nTmpR;

				pRgbUp++;
				pRgbCur++;
				pRgbDown++;
				pRgbNew++;
			}
		}

		memcpy(pRgbData,pNew,nStrideBytes * nHeight);
		delete	pNew;

		return	true;
	}


	enum	CONVOLUTION_TYPE
	{
		CONV_DUMMY = 0,

		CONV_EMBOSS01,
		CONV_EMBOSS02,
		CONV_EMBOSS03,
		CONV_EMBOSS04,
		CONV_EMBOSS05,
		CONV_EMBOSS06,
		CONV_EMBOSS07,
		CONV_EMBOSS08,
		CONV_EMBOSS09,
		CONV_EMBOSS10,
		CONV_SOBEL01,
		CONV_SOBEL02,
		CONV_PREWITT01,
		CONV_PREWITT02,
		CONV_KIRSH01,
		CONV_KIRSH02,
		CONV_EDGE01,
		CONV_EDGE02,
		CONV_EDGE03,
		CONV_EDGE04,
		CONV_EDGE05,
		CONV_EDGE06,
		CONV_EDGE07,
		CONV_EDGEENHANCE01,
		CONV_AVRREMOVE01,
		CONV_SHARP01,
		CONV_SHARP02,
		CONV_SHARP03,
		CONV_SHARP04,
		CONV_SOFT01,
		CONV_SOFT02,
		CONV_SOFT03,
		CONV_SOFT04,
		CONV_SOFT05,
		CONV_SOFT06,
		CONV_SOFT07,
		CONV_SOFT08,
		CONV_LAPLACIAN01,
		CONV_LAPLACIAN02,


		CONV_DUMMY_END
	};



	bool	Convolution(ULONG nWidth,ULONG nHeight,long nStrideBytes,BYTE* pRgbData,CONVOLUTION_TYPE enumType,bool bNotDivide=false)
	{
		int		pnOperate[9];

		//パラメータ参照元
		// http://www.rebol.net/rebcode/demos/convolution-rc.r
		//

		switch(enumType)
		{
		case	CONV_DUMMY:
		case	CONV_DUMMY_END:
			//ダミー処理パラメータ
			pnOperate[0] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[1] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[2] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[3] = 0;
			pnOperate[4] = 1;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = 0;
			break;

		case	CONV_EMBOSS01:
			//エンボス処理パラメータ1
			pnOperate[0] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[1] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[2] = 0;			//[  0 ][  0 ][ -8 ]
			pnOperate[3] = 0;
			pnOperate[4] = 1;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = -1;
			break;

		case	CONV_EMBOSS02:
			//エンボス処理パラメータ2
			pnOperate[0] = 2;			//[  2 ][  0 ][  0 ]
			pnOperate[1] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[2] = 0;			//[  0 ][  0 ][ -1 ]
			pnOperate[3] = 0;
			pnOperate[4] = -1;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = -1;
			break;

		case	CONV_EMBOSS03:
			//エンボス処理パラメータ3
			pnOperate[0] = -2;			//[ -2 ][ -1 ][  0 ]
			pnOperate[1] = -1;			//[ -1 ][  1 ][  1 ]
			pnOperate[2] = 0;			//[  0 ][  1 ][  2 ]
			pnOperate[3] = -1;
			pnOperate[4] = 1;
			pnOperate[5] = 1;
			pnOperate[6] = 0;
			pnOperate[7] = 1;
			pnOperate[8] = 2;
			break;

		case	CONV_EMBOSS04:
			//エンボス処理パラメータ4Laplascian
			pnOperate[0] = -1;			//[ -1 ][  0 ][ -1 ]
			pnOperate[1] = 0;			//[  0 ][  4 ][  0 ]
			pnOperate[2] = -1;			//[ -1 ][  0 ][ -1 ]
			pnOperate[3] = 0;
			pnOperate[4] = 4;
			pnOperate[5] = 0;
			pnOperate[6] = -1;
			pnOperate[7] = 0;
			pnOperate[8] = -1;
			break;

		case	CONV_EMBOSS05:
			//エンボス処理パラメータ5全方向
		case	CONV_EDGE04:
			//エッジ検出処理パラメータ4
			pnOperate[0] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[1] = -1;			//[ -1 ][  8 ][ -1 ]
			pnOperate[2] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[3] = -1;
			pnOperate[4] = 8;
			pnOperate[5] = -1;
			pnOperate[6] = -1;
			pnOperate[7] = -1;
			pnOperate[8] = -1;
			break;

		case	CONV_EMBOSS06:
			//エンボス処理パラメータ6水平方向
			pnOperate[0] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[1] = 0;			//[ -1 ][  2 ][ -1 ]
			pnOperate[2] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[3] = -1;
			pnOperate[4] = 2;
			pnOperate[5] = -1;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = 0;
			break;

		case	CONV_EMBOSS07:
			//エンボス処理パラメータ7垂直方向
			pnOperate[0] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[1] = -1;			//[  0 ][  2 ][  0 ]
			pnOperate[2] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[3] = 0;
			pnOperate[4] = 0;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = -1;
			pnOperate[8] = 0;
			break;

		case	CONV_EMBOSS08:
			//エンボス処理パラメータ8水平垂直
			pnOperate[0] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[1] = -1;			//[ -1 ][  4 ][ -1 ]
			pnOperate[2] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[3] = -1;
			pnOperate[4] = 4;
			pnOperate[5] = -1;
			pnOperate[6] = 0;
			pnOperate[7] = -1;
			pnOperate[8] = 0;
			break;

		case	CONV_EMBOSS09:
			//エンボス処理パラメータ9Lossy
			pnOperate[0] = 1;			//[  1 ][ -2 ][  1 ]
			pnOperate[1] = -2;			//[  1 ][ -2 ][  4 ]
			pnOperate[2] = 1;			//[ -2 ][ -1 ][ -2 ]
			pnOperate[3] = -2;
			pnOperate[4] = 4;
			pnOperate[5] = -2;
			pnOperate[6] = -2;
			pnOperate[7] = -1;
			pnOperate[8] = -2;
			break;

		case	CONV_EMBOSS10:
			//エンボス処理パラメータ10
			pnOperate[0] = -4;			//[ -4 ][ -2 ][  0 ]
			pnOperate[1] = -2;			//[ -2 ][  2 ][  2 ]
			pnOperate[2] = 0;			//[  0 ][  2 ][  4 ]
			pnOperate[3] = -2;
			pnOperate[4] = 2;
			pnOperate[5] = 2;
			pnOperate[6] = 0;
			pnOperate[7] = 2;
			pnOperate[8] = 4;
			break;

		case	CONV_SOBEL01:
			//Sobel処理パラメータ水平
			pnOperate[0] = 1;			//[  1 ][  2 ][  1 ]
			pnOperate[1] = 2;			//[  0 ][  0 ][  0 ]
			pnOperate[2] = 1;			//[ -1 ][ -2 ][ -1 ]
			pnOperate[3] = 0;
			pnOperate[4] = 0;
			pnOperate[5] = 0;
			pnOperate[6] = -1;
			pnOperate[7] = -2;
			pnOperate[8] = -1;
			break;

		case	CONV_SOBEL02:
			//Sobel処理パラメータ垂直
			pnOperate[0] = 1;			//[  1 ][  0 ][ -1 ]
			pnOperate[1] = 0;			//[  2 ][  0 ][ -2 ]
			pnOperate[2] = -1;			//[  1 ][  0 ][ -1 ]
			pnOperate[3] = 2;
			pnOperate[4] = 0;
			pnOperate[5] = -2;
			pnOperate[6] = 1;
			pnOperate[7] = 0;
			pnOperate[8] = -1;
			break;

		case	CONV_PREWITT01:
			//Prewitt処理パラメータ水平
			pnOperate[0] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[1] = 1;			//[  0 ][  0 ][  0 ]
			pnOperate[2] = 1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[3] = 0;
			pnOperate[4] = 0;
			pnOperate[5] = 0;
			pnOperate[6] = -1;
			pnOperate[7] = -1;
			pnOperate[8] = -1;
			break;

		case	CONV_PREWITT02:
			//Prewitt処理パラメータ垂直
			pnOperate[0] = 1;			//[  1 ][  0 ][ -1 ]
			pnOperate[1] = 0;			//[  1 ][  0 ][ -1 ]
			pnOperate[2] = -1;			//[  1 ][  0 ][ -1 ]
			pnOperate[3] = 1;
			pnOperate[4] = 0;
			pnOperate[5] = -1;
			pnOperate[6] = 1;
			pnOperate[7] = 0;
			pnOperate[8] = -1;
			break;

		case	CONV_KIRSH01:
			//Kirsh処理パラメータ水平
			pnOperate[0] = 5;			//[  5 ][  5 ][  5 ]
			pnOperate[1] = 5;			//[ -3 ][ -3 ][ -3 ]
			pnOperate[2] = 5;			//[ -3 ][ -3 ][ -3 ]
			pnOperate[3] = -3;
			pnOperate[4] = -3;
			pnOperate[5] = -3;
			pnOperate[6] = -3;
			pnOperate[7] = -3;
			pnOperate[8] = -3;
			break;

		case	CONV_KIRSH02:
			//Kirsh処理パラメータ垂直
			pnOperate[0] = 5;			//[  5 ][ -3 ][ -3 ]
			pnOperate[1] = -3;			//[  5 ][ -3 ][ -3 ]
			pnOperate[2] = -3;			//[  5 ][ -3 ][ -3 ]
			pnOperate[3] = 5;
			pnOperate[4] = -3;
			pnOperate[5] = -3;
			pnOperate[6] = 5;
			pnOperate[7] = -3;
			pnOperate[8] = -3;
			break;

		case	CONV_EDGE01:
			//エッジ検出処理パラメータ1
			pnOperate[0] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[1] = 1;			//[  1 ][ -4 ][  1 ]
			pnOperate[2] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[3] = 1;
			pnOperate[4] = -4;
			pnOperate[5] = 1;
			pnOperate[6] = 0;
			pnOperate[7] = 1;
			pnOperate[8] = 0;
			break;

		case	CONV_EDGE02:
			//エッジ検出処理パラメータ2
			pnOperate[0] = -5;			//[ -5 ][  0 ][  0 ]
			pnOperate[1] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[2] = 0;			//[  0 ][  0 ][ -5 ]
			pnOperate[3] = 0;
			pnOperate[4] = 0;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = -5;
			break;

		case	CONV_EDGE03:
			//エッジ検出処理パラメータ3
			pnOperate[0] = -125;		//[ -125 ][ -125 ][ -125 ]
			pnOperate[1] = -125;		//[ -125 ][ 1000 ][ -125 ]
			pnOperate[2] = -125;		//[ -125 ][ -125 ][ -125 ]
			pnOperate[3] = -125;
			pnOperate[4] = 1000;
			pnOperate[5] = -125;
			pnOperate[6] = -125;
			pnOperate[7] = -125;
			pnOperate[8] = -125;
			break;

		//case	CONV_EDGE04:
		//	//エッジ検出処理パラメータ4
		//	break;

		case	CONV_EDGE05:
			//エッジ検出処理パラメータ5
			pnOperate[0] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[1] = -1;			//[  2 ][  2 ][  2 ]
			pnOperate[2] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[3] = 2;
			pnOperate[4] = 2;
			pnOperate[5] = 2;
			pnOperate[6] = -1;
			pnOperate[7] = -1;
			pnOperate[8] = -1;
			break;

		case	CONV_EDGE06:
			//エッジ検出処理パラメータ6
			pnOperate[0] = -5;			//[ -5 ][ -5 ][ -5 ]
			pnOperate[1] = -5;			//[ -5 ][ 39 ][ -5 ]
			pnOperate[2] = -5;			//[ -5 ][ -5 ][ -5 ]
			pnOperate[3] = -5;
			pnOperate[4] = 39;
			pnOperate[5] = -5;
			pnOperate[6] = -5;
			pnOperate[7] = -5;
			pnOperate[8] = -5;
			break;

		case	CONV_EDGE07:
			//エッジ検出処理パラメータ7
			pnOperate[0] = 0;			//[  0 ][  2 ][  0 ]
			pnOperate[1] = 0;			//[  2 ][ -8 ][  2 ]
			pnOperate[2] = 0;			//[  0 ][  2 ][  0 ]
			pnOperate[3] = -1;
			pnOperate[4] = 1;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = 0;
			break;

		case	CONV_EDGEENHANCE01:
			//エッジ強調処理パラメータ
			pnOperate[0] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[1] = 0;			//[ -1 ][  1 ][  0 ]
			pnOperate[2] = 0;			//[  0 ][  0 ][  0 ]
			pnOperate[3] = -1;
			pnOperate[4] = 1;
			pnOperate[5] = 0;
			pnOperate[6] = 0;
			pnOperate[7] = 0;
			pnOperate[8] = 0;
			break;

		case	CONV_AVRREMOVE01:
			//平均削除処理パラメータ
			pnOperate[0] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[1] = -1;			//[ -1 ][  9 ][ -1 ]
			pnOperate[2] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[3] = -1;
			pnOperate[4] = 9;
			pnOperate[5] = -1;
			pnOperate[6] = -1;
			pnOperate[7] = -1;
			pnOperate[8] = -1;
			break;

		case	CONV_SHARP01:
			//シャープ処理パラメータ1
			pnOperate[0] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[1] = -1;			//[ -1 ][ 16 ][ -1 ]
			pnOperate[2] = -1;			//[ -1 ][ -1 ][ -1 ]
			pnOperate[3] = -1;
			pnOperate[4] = 16;
			pnOperate[5] = -1;
			pnOperate[6] = -1;
			pnOperate[7] = -1;
			pnOperate[8] = -1;
			break;

		case	CONV_SHARP02:
			//シャープ処理パラメータ2
			pnOperate[0] = 0;			//[  0 ][ -2 ][  0 ]
			pnOperate[1] = -2;			//[ -2 ][ 11 ][ -2 ]
			pnOperate[2] = 0;			//[  0 ][ -2 ][  0 ]
			pnOperate[3] = -2;
			pnOperate[4] = 11;
			pnOperate[5] = -2;
			pnOperate[6] = 0;
			pnOperate[7] = -2;
			pnOperate[8] = 0;
			break;

		case	CONV_SHARP03:
			//シャープ処理パラメータ3
			pnOperate[0] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[1] = -1;			//[ -1 ][  5 ][ -1 ]
			pnOperate[2] = 0;			//[  0 ][ -1 ][  0 ]
			pnOperate[3] = -1;
			pnOperate[4] = 5;
			pnOperate[5] = -1;
			pnOperate[6] = 0;
			pnOperate[7] = -1;
			pnOperate[8] = 0;
			break;

		case	CONV_SHARP04:
			//シャープ処理パラメータ4
			pnOperate[0] = 0;			//[  0 ][ -3 ][  0 ]
			pnOperate[1] = -3;			//[ -3 ][ 24 ][ -3 ]
			pnOperate[2] = 0;			//[  0 ][ -3 ][  0 ]
			pnOperate[3] = -3;
			pnOperate[4] = 24;
			pnOperate[5] = -3;
			pnOperate[6] = 0;
			pnOperate[7] = -3;
			pnOperate[8] = 0;
			break;

		case	CONV_SOFT01:
			//Gaussian blur処理パラメータ
			pnOperate[0] = 1;			//[  1 ][  2 ][  1 ]
			pnOperate[1] = 2;			//[  2 ][  4 ][  2 ]
			pnOperate[2] = 1;			//[  1 ][  2 ][  1 ]
			pnOperate[3] = 2;
			pnOperate[4] = 4;
			pnOperate[5] = 2;
			pnOperate[6] = 1;
			pnOperate[7] = 2;
			pnOperate[8] = 1;
			break;

		case	CONV_SOFT02:
			//Gaussian blur処理パラメータ
			pnOperate[0] = 45;			//[  45 ][ 122 ][  45 ]
			pnOperate[1] = 122;			//[ 122 ][ 322 ][ 122 ]
			pnOperate[2] = 45;			//[  45 ][ 122 ][  45 ]
			pnOperate[3] = 122;
			pnOperate[4] = 322;
			pnOperate[5] = 122;
			pnOperate[6] = 45;
			pnOperate[7] = 122;
			pnOperate[8] = 45;
			break;

		case	CONV_SOFT03:
			//Gaussian blur処理パラメータ
			pnOperate[0] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[1] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[2] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[3] = 1;
			pnOperate[4] = 1;
			pnOperate[5] = 1;
			pnOperate[6] = 0;
			pnOperate[7] = 1;
			pnOperate[8] = 0;
			break;

		case	CONV_SOFT04:
			//ぼかし処理パラメータ
			pnOperate[0] = 1;			//[  1 ][  2 ][  1 ]
			pnOperate[1] = 2;			//[  2 ][  3 ][  2 ]
			pnOperate[2] = 1;			//[  1 ][  2 ][  1 ]
			pnOperate[3] = 2;
			pnOperate[4] = 3;
			pnOperate[5] = 2;
			pnOperate[6] = 1;
			pnOperate[7] = 2;
			pnOperate[8] = 1;
			break;

		case	CONV_SOFT05:
			//ぼかし処理パラメータ
			pnOperate[0] = 625;			//[  625 ][ 1250 ][  625 ]
			pnOperate[1] = 1250;		//[ 1250 ][ 2500 ][ 1250 ]
			pnOperate[2] = 625;			//[  625 ][ 1250 ][  625 ]
			pnOperate[3] = 1250;
			pnOperate[4] = 2500;
			pnOperate[5] = 1250;
			pnOperate[6] = 625;
			pnOperate[7] = 1250;
			pnOperate[8] = 625;
			break;

		case	CONV_SOFT06:
			//ぼかし処理パラメータ
			pnOperate[0] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[1] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[2] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[3] = 1;
			pnOperate[4] = 1;
			pnOperate[5] = 1;
			pnOperate[6] = 1;
			pnOperate[7] = 1;
			pnOperate[8] = 1;
			break;

		case	CONV_SOFT07:
			//ぼかし処理パラメータ
			pnOperate[0] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[1] = 1;			//[  1 ][  0 ][  1 ]
			pnOperate[2] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[3] = 1;
			pnOperate[4] = 0;
			pnOperate[5] = 1;
			pnOperate[6] = 0;
			pnOperate[7] = 1;
			pnOperate[8] = 0;
			break;

		case	CONV_SOFT08:
			//ぼかし処理パラメータ
			pnOperate[0] = 2;			//[  2 ][  2 ][  2 ]
			pnOperate[1] = 2;			//[  2 ][  1 ][  2 ]
			pnOperate[2] = 2;			//[  2 ][  2 ][  2 ]
			pnOperate[3] = 2;
			pnOperate[4] = 1;
			pnOperate[5] = 2;
			pnOperate[6] = 2;
			pnOperate[7] = 2;
			pnOperate[8] = 2;
			break;

		case	CONV_LAPLACIAN01:
			//ラプラシアン処理パラメータ全方向
			pnOperate[0] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[1] = 1;			//[  1 ][ -8 ][  1 ]
			pnOperate[2] = 1;			//[  1 ][  1 ][  1 ]
			pnOperate[3] = 1;
			pnOperate[4] = -8;
			pnOperate[5] = 1;
			pnOperate[6] = 1;
			pnOperate[7] = 1;
			pnOperate[8] = 1;
			break;

		case	CONV_LAPLACIAN02:
			//ラプラシアン処理パラメータ上下左右
			pnOperate[0] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[1] = 1;			//[  1 ][ -4 ][  1 ]
			pnOperate[2] = 0;			//[  0 ][  1 ][  0 ]
			pnOperate[3] = 1;
			pnOperate[4] = -4;
			pnOperate[5] = 1;
			pnOperate[6] = 0;
			pnOperate[7] = 1;
			pnOperate[8] = 0;
			break;

		default:
			ATLASSERT(0);
			return	false;
		}

		return	Convolution(nWidth,nHeight,nStrideBytes,pRgbData,pnOperate,bNotDivide);
	}






	bool	OnPaint(HDC hDC,int nX,int nY,CONVOLUTION_TYPE enumType)
	{
		////////////////////////////
		//GDI+初期化
		//本当はアプリケーションの初期化時に行うべきだがソースコードの簡易化のためOnPaintに配置
		ULONG_PTR	_nToken;
		Gdiplus::GdiplusStartupInput _sGdiplusStartupInput;
		Gdiplus::GdiplusStartup(&_nToken,&_sGdiplusStartupInput,NULL);


		////////////////////////////
		//画像読み込み
		//ソースコード簡易化のため描画毎に読み出す
		Gdiplus::Bitmap*	pImage;
		Gdiplus::Graphics	cGraphics(hDC);

		pImage = Gdiplus::Bitmap::FromFile(L"c:\\test.jpg",TRUE);


		////////////////////////////
		//画像表示(画像処理前)
		cGraphics.DrawImage(pImage,(Gdiplus::REAL)nX,(Gdiplus::REAL)nY
			,(Gdiplus::REAL)pImage->GetWidth(),(Gdiplus::REAL)pImage->GetHeight());


		////////////////////////////
		//画像処理
		//
		RGBTRIPLE*	pTmp;
		Gdiplus::BitmapData		bitmapData;

		pImage->LockBits(&Gdiplus::Rect(0,0,pImage->GetWidth(),pImage->GetHeight())
			,Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeWrite,PixelFormat24bppRGB,&bitmapData);

		pTmp = (RGBTRIPLE*)bitmapData.Scan0;
		Convolution(pImage->GetWidth(),pImage->GetHeight(),bitmapData.Stride,(BYTE*)pTmp,enumType);
		pImage->UnlockBits(&bitmapData);



		////////////////////////////
		//画像表示(画像処理後)
		cGraphics.DrawImage(pImage,(Gdiplus::REAL)pImage->GetWidth() + 2 + nX,(Gdiplus::REAL)nY
			,(Gdiplus::REAL)pImage->GetWidth(),(Gdiplus::REAL)pImage->GetHeight());

		////////////////////////////
		//画像開放
		delete	pImage;

		////////////////////////////
		//GDI+開放処理
		//本当はアプリケーションの終了時に行うべきだがソースコードの簡易化のため行わない
		//Gdiplus::GdiplusShutdown(_nToken);

		return	true;
	}




	LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		int			i;
		int			nY;
		CPaintDC	dc(m_hWnd);

		nY = 0;
		for(i = 0; i < 5; i++)
		{
			OnPaint(dc.m_hDC,0,nY,(CONVOLUTION_TYPE)(i + 1 + 5*7));
			nY += 202;
		}

		return	0;
	}
};
※ソースコード中に既知のバグというかミスコーディングがあります。画像にどんな 変化が加わるかを見るだけのテスト用途のため修正はしていません。



カテゴリー「VC++ TIPS」 のエントリー