前幾天要做一段程序,把文字和位圖圖像合成並保存為位圖文件。但問了好久都沒人給一個滿意的答復,只好在黑暗中摸索,費了一番功夫,實現了圖像與文字的合成,並且可用鼠標拖動文字。現在我把代碼貼出,希望能給需要的朋友以幫助。
一、關鍵函數 1.
int SetDIBits(
HDC hdc, // 兼容DC的句柄
HBITMAP hbmp, // 兼容位圖的句柄
UINT uStartScan, // 掃描起始行的編號
UINT cScanLines, // 掃描的行的數目
CONST VOID *lpvBits, // 位圖緩沖區的指針,要求已經分配空間
CONST BITMAPINFO *lpbmi, // 位圖信息
UINT fuColorUse // 顏色格式
);
這個函數把位圖數據一個像素一個像素的貼到一個兼容位圖上,hdc是選擇了兼容位圖的兼容DC。
2.
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);
}
三、圖例
添加文字的效果圖
四、結束語
有關位圖的讀寫,參考了VC知識庫在線雜志第21期中胡卓玮朋友寫的《位圖文件讀寫綜述》一文。
本程序在win2000、vc6、174*218 24位真彩色圖片下調試通過。
本程序存在以下問題:
1.不能在兼容DC裡選擇畫筆、字體;
2.從兼容位圖裡取數據,僅對真彩色位圖有效。
如果您知道如何解決以上問題,歡迎賜教。
地址:南京世紀新訊科技有限公司;msn:[email protected]
本文配套源碼