19,468
社区成员
发帖
与我相关
我的任务
分享
BYTE* Get24BitPixels(HBITMAP pBitmap)
{
BITMAP bmpBmp;
LPBITMAPINFO pbmiInfo;
BITMAPINFO bmiInfo;
WORD wBmpWidth, wBmpHeight;
GetObject(pBitmap, sizeof(bmpBmp), &bmpBmp);
pbmiInfo = (LPBITMAPINFO)&bmpBmp;
wBmpWidth = (WORD)pbmiInfo->bmiHeader.biWidth;
wBmpWidth -= (wBmpWidth%4);
wBmpHeight = (WORD)pbmiInfo->bmiHeader.biHeight;
BYTE *pPixels = new BYTE[wBmpWidth*wBmpHeight*3];
if (!pPixels) return NULL;
HDC hDC =::GetWindowDC(NULL);
bmiInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmiInfo.bmiHeader.biWidth = wBmpWidth;
bmiInfo.bmiHeader.biHeight = -wBmpHeight;
bmiInfo.bmiHeader.biPlanes = 1;
bmiInfo.bmiHeader.biBitCount = 24;
bmiInfo.bmiHeader.biCompression = BI_RGB;
bmiInfo.bmiHeader.biSizeImage = wBmpWidth*wBmpHeight*3;
bmiInfo.bmiHeader.biXPelsPerMeter = 0;
bmiInfo.bmiHeader.biYPelsPerMeter = 0;
bmiInfo.bmiHeader.biClrUsed = 0;
bmiInfo.bmiHeader.biClrImportant = 0;
// get pixels from the original bitmap converted to 24bits
int iRes = GetDIBits(hDC, pBitmap, 0, wBmpHeight, (LPVOID)pPixels, &bmiInfo, DIB_RGB_COLORS);
// release the device context
::ReleaseDC(NULL, hDC);
// if failed, cancel the operation.
if (!iRes)
{
delete pPixels;
return NULL;
};
// return the pixel array
return pPixels;
}
// 复制图像
memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);
FILE *fpTargt = fopen("C:\\Documents and Settings\\Administrator.IBM-157A5094478\\桌面\\cn_10.bmp", "wb");
fwrite(lpDIBBits, lWidth * lHeight, 1, fpTargt);
fclose(fpTargt);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
/*************************************************************************
*
* 函数名称:
* ThresholdDIB()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数)
* LONG lHeight - 源图像高度(象素数)
*
* 返回值:
* BOOL - 运算成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用于对图像进行阈值分割运算:二值化
*
************************************************************************/
BOOL WINAPI ThresholdDIB(LPSTR lpDIBBits,LONG lWidth, LONG lHeight)
{
// 指向源图像的指针
LPSTR lpSrc;
// 指向缓存图像的指针
LPSTR lpDst;
// 指向缓存DIB图像的指
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
//循环变量
long i;
long j;
//像素值
unsigned char pixel;
//直方图数组
long lHistogram[256];
//阈值,最大灰度值与最小灰度值,两个区域的平均灰度值
unsigned char iThreshold,iNewThreshold,iMaxGrayValue,iMinGrayValue,iMean1GrayValue,iMean2GrayValue;
//用于计算区域灰度平均值的中间变量
long lP1,lP2,lS1,lS2;
//迭代次数
int iIterationTimes;
// 图像每行的字节数
LONG lLineBytes;
// 暂时分配内存,以保存新图像
hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);
if (hNewDIBBits == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 初始化新分配的内存,设定初始值为255
lpDst = (char *)lpNewDIBBits;
memset(lpDst, (BYTE)255, lWidth * lHeight);
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
for (i = 0; i < 256;i++)
{
lHistogram[i]=0;
}
//获得直方图
iMaxGrayValue = 0;
iMinGrayValue = 255;
for (i = 0;i < lWidth ;i++)
{
for(j = 0;j < lHeight ;j++)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
pixel = (unsigned char)*lpSrc;
lHistogram[pixel]++;
//修改最大,最小灰度值
if(iMinGrayValue > pixel)
{
iMinGrayValue = pixel;
}
if(iMaxGrayValue < pixel)
{
iMaxGrayValue = pixel;
}
}
}
//迭代求最佳阈值
iNewThreshold = (iMinGrayValue + iMaxGrayValue)/2;
iThreshold = 0;
for(iIterationTimes = 0; iThreshold != iNewThreshold && iIterationTimes < 100;iIterationTimes ++)
{
iThreshold = iNewThreshold;
lP1 =0;
lP2 =0;
lS1 = 0;
lS2 = 0;
//求两个区域的灰度平均值
for (i = iMinGrayValue;i < iThreshold;i++)
{
lP1 += lHistogram[i]*i;
lS1 += lHistogram[i];
}
iMean1GrayValue = (unsigned char)(lP1 / lS1);
for (i = iThreshold+1;i < iMaxGrayValue;i++)
{
lP2 += lHistogram[i]*i;
lS2 += lHistogram[i];
}
iMean2GrayValue = (unsigned char)(lP2 / lS2);
iNewThreshold = (iMean1GrayValue + iMean2GrayValue)/2;
}
//根据阈值将图像二值化
for (i = 0;i < lWidth ;i++)
{
for(j = 0;j < lHeight ;j++)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
// 指向目标图像倒数第j行,第i个象素的指针
lpDst = (char *)lpNewDIBBits + lLineBytes * j + i;
pixel = (unsigned char)*lpSrc;
if(pixel <= iThreshold)
{
*lpDst = (unsigned char)0;
}
else
{
*lpDst = (unsigned char)255;
}
}
}
// 复制图像
memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 返回
return TRUE;
}