备注:本文所有操作都是基于Windows的位图句柄HBITMAP的。
1、首先,VC++为了支持多图片格式,我引用了GDI+来加载各种图像。
GDI+使用前,切记:
#include <GdiPlus.h>
#pragma comment (lib,"GdiPlus")
程序开始时:
Gdiplus::GdiplusStartup(&m_pGdiplus,&m_GdiplusSt,NULL);
程序终止前:
Gdiplus::GdiplusShutdown(m_pGdiplus);
2、图像的分割实现,主要方法就是把图像的句柄放到一个内存兼容DC上,再创建一个内存兼容DC和一个内存兼容位图句柄,通过BitBlt你想怎么切都可以,实际上就是一个DC区域拷贝的问题。
贴代码:
HBITMAP CImageDemoDlg::GetBitmapRect( HDC hDC, const CRect& rect )
{
ASSERT(hDC);
HDC hDesDC=NULL;
hDesDC=CreateCompatibleDC(hDC);
HBITMAP hDesBitmap=CreateCompatibleBitmap(hDC,rect.Width(),rect.Height());
HBITMAP hOldBitmap=(HBITMAP)::SelectObject(hDesDC,hDesBitmap);
::BitBlt(hDesDC,0,0,rect.Width(),rect.Height(),\
hDC,rect.left,rect.top,SRCCOPY);
hDesBitmap=(HBITMAP)::SelectObject(hDesDC,hOldBitmap);
DeleteDC(hDesDC);
return hDesBitmap;
}
3、接着就是彩色图像转灰度图像了,这个相当简单,用GetBitmapBits把位图颜色值写入内存中,然后把像素值一个个地读出来转换成灰度颜色,然后写到内存里,再用SetBitmapBits写到原来的那个位图句柄中,OK,灰度图转换完成。
贴代码:
//灰度处理
#define GET_GRAY_VALUE(x) 0.110*GetBValue(x)+0.588*GetGValue(x)+0.302*GetRValue(x)
HBITMAP CImageDemoDlg::GetGrayBitmap( HBITMAP hResBitmap ,int& nWhiteCount,int& nBackCount)
{
nWhiteCount=0;
nBackCount=0;
ASSERT(hResBitmap);
HBITMAP hDesBitmap=NULL;
BITMAP bm;
GetObject(hResBitmap,sizeof(bm),&bm);
LONG lSize=bm.bmWidth*bm.bmBitsPixel*bm.bmHeight/8;
int nSize=bm.bmWidth*bm.bmHeight/10;
HLOCAL hMem=LocalAlloc(LHND,lSize);
byte* pData=(byte*)LocalLock(hMem);
::GetBitmapBits(hResBitmap,lSize,pData);
byte* pHead=pData;
byte* pTail=pData+lSize-4;
DWORD dwColor1=0;
DWORD dwColor2=0;
byte bGray1=0;
byte bGray2=0;
while ( pTail>pHead )
{
memcpy(&dwColor1,pHead,4);
memcpy(&dwColor2,pTail,4);
bGray1=GET_GRAY_VALUE(dwColor1);
if ( bGray1<128 )
nBackCount++;
else
nWhiteCount++;
bGray2=GET_GRAY_VALUE(dwColor2);
if ( bGray2<128 )
nBackCount++;
else
nWhiteCount++;
dwColor1=RGB(bGray1,bGray1,bGray1);
dwColor2=RGB(bGray2,bGray2,bGray2);
memcpy(pHead,&dwColor1,4);
memcpy(pTail,&dwColor2,4);
pHead+=4;
pTail-=4;
}
HDC hDC=::GetDC(m_hWnd);
hDesBitmap=CreateCompatibleBitmap(hDC,bm.bmWidth,bm.bmHeight);
LONG lRet=::SetBitmapBits(hDesBitmap,lSize,pData);
LocalUnlock(hMem);
LocalFree(hMem);
::ReleaseDC(m_hWnd,hDC);
return hDesBitmap;
}
4、统计黑白像素点的个数和所占比例
在进行像素的变换时已经对这个进行了记录,接下来用GDI的画刷把比例图画出来。
5、在OnDraw中把原图、分割图、灰度分割图、黑色像素比例图绘制出来。
效果图:
源码下载地址:代码
欢迎指教。