解説
RGBのカラー画像CBitmap m_cBitmapをグレースケール(白黒画像)に変換する。
原理的には変換にはYCrCb変換のY値、つまり輝度を求めるのに使われる下記の式を使用。
出力画素 = (0.299 * R + 0.587 * G + 0.114 * B)
ただし浮動小数点演算だとクロック数を多く消費するので以下の整数演算式を使用。
出力画素 = (0.299 * R + 0.587 * G + 0.114 * B) * 256 / 256
= (77 * R + 150 * G + 29 * B) >> 8
厳密に変換しているわけではないので変換後の画像は元の画像と同じく1ピクセル当たり3Bytesを消費している


// // グレースケールへの変更 // // ※ 1pixel 3Byte使用は変わらず! // // YCrCbのY値つまり輝度を用いることによる変換 // 出力画素 = (0.299 * R + 0.587 * G + 0.114 * B) // bool CDIBitmap::ConvertToGrayScale(void) { TRY { int i; int j; int n; int nGray; BITMAP sBitmap; DWORD dwLineBytes; DWORD dwSizeImage; BYTE* lpBuffer; m_lpcBitmap->GetBitmap(&sBitmap); dwSizeImage = (DWORD)(sBitmap.bmWidthBytes * sBitmap.bmHeight); dwLineBytes = sBitmap.bmWidthBytes; lpBuffer = new BYTE[dwSizeImage + 1]; m_lpcBitmap->GetBitmapBits(dwSizeImage,lpBuffer); n = 0; for(j = 0; j < sBitmap.bmHeight; j++) { //lpBuffer[n+0]から[n+2]はそれぞれR、G、B値となる for(i = 0;i < sBitmap.bmWidth; i++) { // (0.299 * R + 0.587 * G + 0.114 * B)を整数演算式に変換して使用 nGray = (int)(77 * lpBuffer[n + 0] + 150 * lpBuffer[n + 1] + 29 * lpBuffer[n + 2]) >> 8; lpBuffer[n + 0] = (BYTE)nGray; lpBuffer[n + 1] = (BYTE)nGray; lpBuffer[n + 2] = (BYTE)nGray; n += 3; } n = j * dwLineBytes; } m_lpcBitmap->SetBitmapBits(dwSizeImage,lpBuffer); //CBitmapへの保存 delete lpBuffer; return true; } CATCH_ALL(e) return false; END_CATCH_ALL }