ENGLISH page is here.
GET DinopSearchBar
サイト内検索:
HOME
VC++ TIPS
ダウンロード
DinopExifReader
DinopSearchBar
DinopSearchBar mini
DinopTabbingBar
for Firefox
大阪湾の生き物
甲子園浜の自然
甲子園浜の干潟
甲子園浜の水中
甲子園浜の野鳥
近畿の山々
植物図鑑
箕面マップ
水中機材
カメラ
ランキング
望遠鏡の世界
顕微鏡の世界
Googleのすべて
GoogleマップAPI
ニュース
読んだ本
日記
変な料理の作り方
遺伝子操作
論文紹介
デイトレード
自動売買でFX
ネットで小遣い稼ぎ
Solaris
電子工作
その他
問い合わせ
VC++用コード集
大阪湾の生き物
水中用機材
since:2000/11/15
dinopcom@gmail.com
www.dinop.comは
だいのっぷ・どっと・こむ
と読んでください。







« 画像のエンボス処理 | メイン | 画像のコンボリュート法によるエッジ検出処理 »

画像のコンボリュート法によるエンボス処理




解説

 コンボリュート法によるエンボス処理。あるピクセルに2、その左上に-4、上と左に-2、右と下に2、 右下に4を乗算した値を2で除算した結果を新しい色値とする。

 ここでは下のような3行3列の処理パラメータのテーブルを用意してシャープ処理を実行してい る。このパラメータの値を変えればエンボス以外にもぼかし処理やエッジ検出処理などさまざま な画像処理を行える。
-4-20
-222
024

実行例



ソースコード

 GDI+を利用した画像処理テストのスケルトンの 画像処理部分を以下のように変更する。



		////////////////////////////
		//画像処理
		//
		UINT		x;
		UINT		y;
		UINT		nPos;
		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;

		int		pnOperate[9];

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

		{
			int			i;
			long		pnRefPos[9];
			int			nTmpR;
			int			nTmpG;
			int			nTmpB;
			int			nDiv;
			int			nStride;
			int			nPixelCount;
			RGBTRIPLE*	prgbTmp;

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

			nStride = bitmapData.Stride / sizeof(RGBTRIPLE);
			nPixelCount = nStride * pImage->GetHeight();

			prgbTmp = new RGBTRIPLE[nPixelCount];
			for(y = 1; y < pImage->GetHeight() - 1; y++)
			{
				nPos = y * nStride;

				for(x = 1; x < pImage->GetWidth() - 1; x++, nPos++)
				{
					//あるピクセルの上下左右のピクセルオフセット計算
					//いちいち計算するのは効率が悪いがソースコードは見やすい?
					pnRefPos[0] = nPos - nStride - 1;
					pnRefPos[1] = pnRefPos[0] + 1;
					pnRefPos[2] = pnRefPos[0] + 2;
					pnRefPos[3] = nPos - 1;
					pnRefPos[4] = nPos;
					pnRefPos[5] = nPos + 1;
					pnRefPos[6] = nPos + nStride - 1;
					pnRefPos[7] = pnRefPos[6] + 1;
					pnRefPos[8] = pnRefPos[6] + 2;

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

						nTmpR += pTmp[pnRefPos[i]].rgbtRed	* pnOperate[i];
						nTmpG += pTmp[pnRefPos[i]].rgbtGreen* pnOperate[i];
						nTmpB += pTmp[pnRefPos[i]].rgbtBlue	* pnOperate[i];
					}
					
					//平均値を求めるために除算
					if(nDiv != 1 && nDiv != 0)
					{
						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;

					prgbTmp[nPos].rgbtBlue	= (BYTE)nTmpB;
					prgbTmp[nPos].rgbtGreen	= (BYTE)nTmpG;
					prgbTmp[nPos].rgbtRed	= (BYTE)nTmpR;
				}
			}

			memcpy(pTmp,prgbTmp,sizeof(RGBTRIPLE) * nPixelCount);
			delete	prgbTmp;
		}
		pImage->UnlockBits(&bitmapData);

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








Copyright (c) 1999-2007 issei. All rights reserved. (運営者情報