图像的分割和灰度处理(VC++实现)

备注:本文所有操作都是基于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中把原图、分割图、灰度分割图、黑色像素比例图绘制出来。

效果图:

图像的分割和灰度处理(VC++实现)_第1张图片

 

源码下载地址:代码

欢迎指教。

 

你可能感兴趣的:(C++,图片,GDI+,gdi)