解説
画像をグレースケール変換して指定されたしきい値を境に2つの色に変える。そのとき 新しい画像と元画像との誤差を右のピクセルに反映させる簡易的な誤差拡散法を採用した。実行例
以下のコードで処理を施した。RGBTRIPLE rgbHigh; RGBTRIPLE rgbLow; rgbHigh.rgbtBlue = 100; rgbHigh.rgbtGreen = 255; rgbHigh.rgbtRed = 255; rgbLow.rgbtBlue = 0; rgbLow.rgbtGreen = 0; rgbLow.rgbtRed = 0; _cImage2.BicolorErrorVarianceEasy(120,rgbHigh,rgbLow);

ソースコード
GDI+を利用した画像処理テストのスケルトン2を 元に拡張する。前に作成した「DnpImage.h」に2階調化関数を追加する。
class CDnpImage : public CDnpImageBase
,public CDnpImageConvolution
,public CDnpColorSpaceHLS
,public CDnpColorSpaceHSV
{
public:
//
// 画像の簡易誤差拡散法による2階調化
//
//グレースケール変換したときの色値がcbThresholdを超えていればrgbHighに、
//下回ればrgbLowに変えて2階調化する。新しい値の誤差を次にピクセルに割り
//振る単純な誤差拡散法による
//
bool BicolorErrorVarianceEasy(BYTE cbThreshold,RGBTRIPLE rgbHigh,RGBTRIPLE rgbLow)
{
if(IsValidImage() == false)
return false;
int nStrideBytes;
bool ret;
UINT x;
UINT y;
UINT nWidth;
UINT nHeight;
BYTE* pData;
RGBTRIPLE* pRGB;
BYTE cbHigh;
BYTE cbLow;
int nError;
cbHigh = (BYTE)((77 * rgbHigh.rgbtRed + 150 * rgbHigh.rgbtGreen + 29 * rgbHigh.rgbtBlue) >> 8);
cbLow = (BYTE)((77 * rgbLow .rgbtRed + 150 * rgbLow .rgbtGreen + 29 * rgbLow .rgbtBlue) >> 8);
nWidth = GetWidth();
nHeight = GetHeight();
ret = LockBits(&pData,&nStrideBytes);
if(ret == false)
return false;
for(y = 0; y < nHeight; y++)
{
nError = 0;
pRGB = (RGBTRIPLE*)pData;
for(x = 0; x < nWidth; x++)
{
int nTmp;
nTmp = (BYTE)((77 * pRGB[x].rgbtRed + 150 * pRGB[x].rgbtGreen + 29 * pRGB[x].rgbtBlue) >> 8);
nTmp -= nError;
if(nTmp > 255)
nTmp = 255;
if(nTmp < 0)
nTmp = 0;
if(nTmp > (int)cbThreshold)
{
pRGB[x] = rgbHigh;
nError = cbHigh - nTmp;
}
else
{
pRGB[x] = rgbLow;
nError = cbLow - nTmp;
}
if(nError > 255)
nError = 255;
if(nError < 0)
nError = 0;
}
pData += nStrideBytes;
}
UnlockBits();
return true;
}
。。。。省略。。。。
};
