在进行图像处理时,HBITMAP是一个非常重要的概念。HBITMAP是一个句柄,用于引用位图图像。本文将介绍如何使用HBITMAP进行基本的图像操作,包括创建、绘制和最终的资源清理。对于初学者来说,这是一个非常实用的参考。
首先,需要一个背景图像,这个图像可以通过HBITMAP句柄来引用。HBITMAP可以是之前操作的结果,也可以通过CreateBitmap()函数创建,或者直接引用资源。以下是使用C++代码加载一个位图资源的示例:
HBITMAP hbitmap = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1));
接下来,可以从hbitmap中提取基本属性:
BITMAP bm;
GetObject(hbitmap, sizeof(BITMAP), &bm);
long width = bm.bmWidth;
long height = bm.bmHeight;
在创建了背景图像之后,需要创建一个内存设备上下文(Device Context),并在其中选择一个新的位图。以下是创建内存设备上下文和新位图的步骤:
BITMAPINFO bmInfo;
memset(&bmInfo.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmInfo.bmiHeader.biWidth = width;
bmInfo.bmiHeader.biHeight = height;
bmInfo.bmiHeader.biPlanes = 1;
bmInfo.bmiHeader.biBitCount = 24;
HDC pDC = ::GetDC(0);
HDC TmpDC = CreateCompatibleDC(pDC);
BYTE *pbase;
HBITMAP TmpBmp = CreateDIBSection(pDC, &bmInfo, DIB_RGB_COLORS, (void**)&pbase, 0, 0);
HGDIOBJ TmpObj = SelectObject(TmpDC, TmpBmp);
TmpDC是设备上下文,可以在其中绘制线条、文本或图像。例如,接下来的代码将在背景图像上绘制一个字符串:
HDC dcBmp = CreateCompatibleDC(TmpDC);
HGDIOBJ TmpObj2 = SelectObject(dcBmp, hbitmap);
BitBlt(TmpDC, 0, 0, width, height, dcBmp, 0, 0, SRCCOPY);
SelectObject(TmpDC, TmpObj2);
DeleteDC(dcBmp);
在绘制文本之前,需要选择一个合适的字体。以下是如何创建和选择字体的步骤:
CFont m_Font;
LOGFONT* m_pLF;
m_pLF = (LOGFONT*)calloc(1, sizeof(LOGFONT));
strncpy(m_pLF->lfFaceName, "Times New Roman", 31);
m_pLF->lfHeight = 64;
m_pLF->lfWeight = 600;
m_pLF->lfItalic = 1;
m_pLF->lfUnderline = 0;
m_Font.CreateFontIndirect(m_pLF);
CDC dc;
dc.Attach(TmpDC);
CFont* pOldFont = NULL;
if (m_Font.m_hObject)
pOldFont = dc.SelectObject(&m_Font);
else
dc.SelectObject(GetStockObject(DEFAULT_GUI_FONT));
dc.SetTextColor(RGB(60, 120, 240));
RECT pos = {40, 40, 0, 0};
dc.SetBkMode(TRANSPARENT);
dc.DrawText("Test", 4, &pos, DT_CALCRECT);
dc.DrawText("Test", 4, &pos, 0);
在完成绘制后,需要进行资源清理。这包括选择回原来的字体、删除字体对象、分离设备上下文以及释放内存:
if (pOldFont) dc.SelectObject(pOldFont);
m_Font.DeleteObject();
dc.Detach();
free(m_pLF);
此时,有两个位图:hbitmap和TmpBmp。可以选择保留旧的和新的图像,或者用TmpBmp替换hbitmap:
DeleteObject(hbitmap);
hbitmap = TmpBmp;
SelectObject(TmpDC, TmpObj);
DeleteDC(TmpDC);