在位图中绘制线条、形状或文本






4.91/5 (22投票s)
在位图上绘制线条、形状或文本的快速参考
引言
本文描述了在位图上绘制线条、形状或文本所需的步骤。这项任务非常简单,但对于初学者来说,一个快速参考可能会很有帮助。
使用 HBITMAP
首先,我们需要一个背景图像,由 hbitmap
句柄引用。hbitmap
可以是先前操作的结果,也可以使用 CreateBitmap()
创建,或者是一个资源。
HBITMAP hbitmap = ::LoadBitmap(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDB_BITMAP1));
从 hbitmap
,我们可以提取基本属性
BITMAP bm;
GetObject( hbitmap, sizeof(BITMAP), &bm );
long width=bm.bmWidth;
long height=bm.bmHeight;
现在让我们创建一个内存设备上下文并选择一个新的位图。
//prepare the bitmap attributes
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;
//create a temporary dc in memory.
HDC pDC = ::GetDC(0);
HDC TmpDC=CreateCompatibleDC(pDC);
//create a new bitmap and select it in the memory dc
BYTE *pbase;
HBITMAP TmpBmp=CreateDIBSection(pDC,
&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
TmpDC
是您可以在其中绘制线条、文本或图像的设备上下文。例如,接下来的几行在背景图像上绘制一个 string
。
//draw the background
HDC dcBmp=CreateCompatibleDC(TmpDC);
HGDIOBJ TmpObj2 = SelectObject(dcBmp,hbitmap);
BitBlt(TmpDC,0,0,width,height,dcBmp,0,0,SRCCOPY);
SelectObject(TmpDC,TmpObj2);
DeleteDC(dcBmp);
//choose the font
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);
//select the font in the dc
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));
//Set text color
dc.SetTextColor(RGB(60,120,240));
//Set text position;
RECT pos = {40,40,0,0};
//draw the text
dc.SetBkMode(TRANSPARENT);
dc.DrawText("Test",4,&pos,DT_CALCRECT);
dc.DrawText("Test",4,&pos,0);
//cleanup
if (pOldFont) dc.SelectObject(pOldFont);
m_Font.DeleteObject();
dc.Detach();
free(m_pLF);
此时,有两个位图:hbitmap
和 TmpBmp
,您可以保留旧图像和新图像,或者用 TmpBmp
替换 hbitmap
。
DeleteObject(hbitmap);
hbitmap=TmpBmp;
最后,我们可以删除临时设备上下文。不要在这里删除 hbitmap
和 TmpBmp
,否则您将丢失位图。
//final cleanup
SelectObject(TmpDC,TmpObj);
DeleteDC(TmpDC);
结论
文章从存储在 HBITMAP
中的背景图像开始,并以新的 HBITMAP
中的新图像结束。这为你在之前、之后和中间可以做的事情提供了高度的灵活性:你可以使用所有 GDI 函数来构建你的图像,例如,你可以使用 CBitmap
,或者像 FreeImage 和 CxImage 这样的图像处理库,来添加效果或将结果保存到文件中。