概述
前几天要做一段程序,把文字和位图图像合成并保存为位图文件。但问了好久都没人给一个满意的答复,只好在黑暗中摸索,费了一番功夫,实现了图像与文字的合成,并且可用鼠标拖动文字。现在我把代码贴出,希望能给需要的朋友以帮助。
关键函数
i
nt SetDIBits(
HDC hdc, // 兼容DC的句柄
HBITMAP hbmp, // 兼容位图的句柄
UINT uStartScan, // 扫描起始行的编号
UINT cScanLines, // 扫描的行的数目
CONST VOID *lpvBits, // 位图缓冲区的指针,要求已经分配空间
CONST BITMAPINFO *lpbmi, // 位图信息
UINT fuColorUse // 颜色格式
);
这个函数把位图数据一个像素一个像素的贴到一个兼容位图上,hdc是选择了兼容位图的兼容DC。
int GetDIBits(
HDC hdc, // 兼容DC的句柄
HBITMAP hbmp, // 兼容位图的句柄
UINT uStartScan, // 扫描起始行的编号
UINT cScanLines, // 扫描的行的数目
LPVOID lpvBits, // 位图缓冲区的指针,要求已经分配空间
LPBITMAPINFO lpbi, // 位图信息
UINT uUsage // 颜色格式
);
这个函数的作用和SetDIBits刚好相反,它把兼容位图内已存在的数据一个像素一个像素的拷贝到数据缓冲区(lpvBits)中。这样程序的实现就比 较明朗了,首先根据位图的尺寸,创建一个兼容位图,然后把图片绘制到兼容位图,接着把文字也写到兼容位图上,然后再从兼容位图得到合成的数据。
关键程序段
CreateMemObject(CDC *pDC, BITMAPINFO *lpbmi, int* pnLineChar)
{
if (NULL == m_pMemDC)
{
m_pMemDC = new CDC();
m_pMemDC->CreateCompatibleDC(pDC);
}
if (m_pMemBmp != NULL)
{
m_pMemDC->SelectObject(m_pOldBmp);
delete m_pMemBmp;
m_pMemBmp = NULL;
}
m_pMemBmp = new CBitmap(); //根据图片的大小创建一个兼容位图
m_pMemBmp->CreateCompatibleBitmap(pDC, m_lpBMPHdr->biWidth, m_lpBMPHdr->biHeight);
m_pOldBmp = m_pMemDC->SelectObject(m_pMemBmp);
m_pMemDC->FillSolidRect(0, 0, m_lpBMPHdr->biWidth, m_lpBMPHdr->biHeight, RGB(255, 255, 255));
//把图像的数据绘制到兼容位图上
SetDIBits(m_pMemDC->GetSafeHdc(), (HBITMAP)m_pMemBmp->m_hObject,
0, m_lpBMPHdr->biHeight, (LPVOID)m_lpDIBits, (BITMAPINFO*)m_lpBMPHdr, DIB_RGB_COLORS);
}
SetBmpText(const CString &strText, BOOL bRepaint)
{
//本函数在位图上添加文本
m_strBmpText = strText;
SetDIBits(m_pMemDC->GetSafeHdc(), (HBITMAP)m_pMemBmp->m_hObject,
0, m_lpBMPHdr->biHeight, (LPVOID)m_lpDIBits, (BITMAPINFO*)m_lpBMPHdr, DIB_RGB_COLORS);
if (m_strBmpText.GetLength() > 0)
{
//制造透明和重影效果
m_pMemDC->SetBkMode(TRANSPARENT);
m_pMemDC->SetTextColor(RGB(0, 0, 0));
m_pMemDC->TextOut(10, 10, m_strBmpText);
m_pMemDC->SetTextColor(RGB(255, 255, 255));
m_pMemDC->TextOut(11, 11, m_strBmpText);
}
if (bRepaint)
{
Invalidate();
}
}
SetSaveBmpPath(LPCTSTR pszPath)
{
//从兼容位图中取出合成的数据
BYTE *pTemp = new BYTE[m_dwImageSize];
ZeroMemory(pTemp, m_dwImageSize);
int nCount = GetDIBits(m_pMemDC->GetSafeHdc(),
(HBITMAP)m_pMemBmp->m_hObject, 0, m_lpBMPHdr->biHeight,
(LPVOID)pTemp, (BITMAPINFO*)m_lpBMPHdr, DIB_RGB_COLORS);
}