分类: C/C++
2011-09-05 21:30:41
前几天要做一段程序,把文字和位图图像合成并保存为位图文件。但问了好久都没人给一个满意的答复,只好在黑暗中摸索,费了一番功夫,实现了图像与文字的合成,并且可用鼠标拖动文字。现在我把代码贴出,希望能给需要的朋友以帮助。 一、关键函数 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.从兼容位图里取数据,仅对真彩色位图有效。 如果您知道如何解决以上问题,欢迎赐教。