《VC的CDib类.doc》由会员分享,可在线阅读,更多相关《VC的CDib类.doc(14页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Visual C+ MFC中没有提供一个专门的类来处理DIB位图,因此,为了方便地使用位图文件,我们有必要派生一个CDib类。类的源代码如下: (1) CDib类的声明 / DIB.h:类CDib声明头文件 #ifndef _DIB_H_ #define _DIB_H_ #include class CDib public: CDib(); CDib(); BOOL Load( const char * ); BOOL Save( const char * ); BOOL Draw( CDC *, int nX = 0, int nY = 0, int nWidth = -1, int nHe
2、ight = -1, int mode = SRCCOPY); BOOL SetPalette( CDC * ); private: CPalette m_Palette; unsigned char *m_pDib, *m_pDibBits; DWORD m_dwDibSize; BITMAPINFOHEADER *m_pBIH; RGBQUAD *m_pPalette; int m_nPaletteEntries; ; #endif (2) CDib类的实现 / DIB.cpp:类CDib实现文件 #include stdafx.h #include DIB.h CDib:CDib() m
3、_pDib = NULL; CDib:CDib() / 如果位图已经被加载,释放内存 if (m_pDib != NULL) delete m_pDib; 下面这个函数非常重要,其功能为加载位图,类似于CBitmap类的LoadBitmap函数: BOOL CDib:Load(const char *psz) C; / 打开位图文件 if (!cf.Open(psz, C) return (FALSE); / 获得位图文件大小,并减去BITMAP的长度 DWORD dwDibSize; dwDibSize = cf.GetLength() - sizeof(BITMAP); / 为DIB位图分
4、配内存 unsigned char *pDib; pDib = new unsigned chardwDibSize; if (pDib = NULL) return (FALSE); BITMAP BFH; / 读取位图文件数据 try / 文件格式是否正确有效 if ( cf.Read(&BFH, sizeof(BITMAP) != sizeof(BITMAP) | BFH.bfType != MB | cf.Read(pDib, dwDibSize) != dwDibSize) delete pDib; return (FALSE); catch (C *e) e-Delete(); d
5、elete pDib; return (FALSE); / delete先前加载的位图 if (m_pDib != NULL) delete m_pDib; / 将临时Dib数据指针和Dib大小变量赋给类成员变量 m_pDib = pDib; m_dwDibSize = dwDibSize; / 为相应类成员变量赋BITMAPINFOHEADER和调色板指针 m_pBIH = (BITMAPINFOHEADER*)m_pDib; m_pPalette = (RGBQUAD*) &m_pDibsizeof(BITMAPINFOHEADER); / 计算调色板中实际颜色数量 m_nPaletteE
6、ntries = 1 biBitCount; if (m_pBIH-biBitCount 8) m_nPaletteEntries = 0; else if (m_pBIH-biClrUsed != 0) m_nPaletteEntries = m_pBIH-biClrUsed; / 为相应类成员变量赋image data指针 m_pDibBits = &m_pDibsizeof(BITMAPINFOHEADER) + m_nPaletteEntries * sizeof (RGBQUAD); / delete先前的调色板 if (m_Palette.GetSafeHandle() != NU
7、LL) m_Palette.DeleteObject(); / 如果位图中存在调色板,创建LOGPALETTE 及CPalette if (m_nPaletteEntries != 0) LOGPALETTE *pLogPal = (LOGPALETTE*)new charsizeof(LOGPALETTE) + m_nPaletteEntries *sizeof(PALETTEENTRY); if (pLogPal != NULL) pLogPal-palVersion = 0x300; pLogPal-palNumEntries = m_nPaletteEntries; for (int
8、i = 0; i palPalEntryi.peRed = m_pPalettei.rgbRed; pLogPal-palPalEntryi.peGreen = m_pPalettei.rgbGreen; pLogPal-palPalEntryi.peBlue = m_pPalettei.rgbBlue; /创建CPalette并释放LOGPALETTE的内存 m_Palette.CreatePalette(pLogPal); delete pLogPal; return (TRUE); /函数功能:保存位图入BMP文件 BOOL CDib:Save(const char *psz) if (
9、m_pDib = NULL) return (FALSE); C; if (!cf.Open(psz, C | C) return (FALSE); try BITMAP BFH; memset(&BFH, 0, sizeof(BITMAP); BFH.bfType = MB; BFH.bfSize = sizeof(BITMAP) + m_dwDibSize; BFH.bfOffBits = sizeof(BITMAP) + sizeof(BITMAPINFOHEADER) + m_nPaletteEntries *sizeof(RGBQUAD); cf.Write(&BFH, sizeof
10、(BITMAP); cf.Write(m_pDib, m_dwDibSize); catch (C *e) e-Delete(); return (FALSE); return (TRUE); 下面这个函数也非常重要,其功能为在pDC指向的CDC中绘制位图,起点坐标为(nX,nY),绘制宽度和高度为nWidth、nHeight,最后一个参数是光栅模式: BOOL CDib:Draw(CDC *pDC, int nX, int nY, int nWidth, int nHeight, int mode) if (m_pDib = NULL) return (FALSE); / 获取位图宽度和高度
11、赋值 if (nWidth = - 1) nWidth = m_pBIH-biWidth; if (nHeight = - 1) nHeight = m_pBIH-biHeight; / 绘制位图 StretchDIBits(pDC-m_hDC, nX, nY, nWidth, nHeight, 0, 0, m_pBIH-biWidth, m_pBIH-biHeight, m_pDibBits, (BITMAPINFO*)m_pBIH, BI_RGB, mode); return (TRUE); /函数功能:设置调色板 BOOL CDib:SetPalette(CDC *pDC) if (m_
12、pDib = NULL) return (FALSE); / 检查当前是否有一个调色板句柄,对于大于256色的位图,为NULL if (m_Palette.GetSafeHandle() = NULL) return (TRUE); / 选择调色板,接着实施之,最后恢复老的调色板 CPalette *pOldPalette; pOldPalette = pDC-SelectPalette(&m_Palette, FALSE); pDC-RealizePalette(); pDC-SelectPalette(pOldPalette, FALSE); return (TRUE); 从整个CDib类
13、的代码中我们可以看出,DIB位图的显示需遵循如下步骤: (1)读取位图,本类中使用pDib = new unsigned chardwDibSize为位图中的信息分配内存,另一种方法是调用API函数CreateDIBSection,譬如: m_hBitmap = :CreateDIBSection(pDC-GetSafeHdc(), (LPBITMAPINFO) m_lpBMPHdr, DIB_RGB_COLORS, (LPVOID*) &m_lpDIBits, NULL, 0); m_hBitmap定义为: HBITMAP m_hBitmap; (2)根据读取的位图信息,计算出调色板大小,然
14、后创建调色板; (3)调用CDib:SetPalette( CDC *pDC )设置调色板,需要用到CDC:SelectPalette及CDC:RealizePalette两个函数; (4)调用CDib:Draw(CDC *pDC, int nX, int nY, int nWidth, int nHeight, int mode)函数绘制位图。在此函数中,真正发挥显示位图作用的是对StretchDIBits API函数的调用。StretchDIBits函数具有缩放功能,其最后一个参数也是光栅操作的模式。 下面给出DIB位图的打开及显示并在其中加入天极网logo的函数源代码。DIB位图父菜单下
15、打开子菜单的单击事件消息处理函数为(其功能为打开位图并显示之): void CBitMapExampleDlg:OnOpendibpic() / 弹出文件对话框,让用户选择位图文件 C (TRUE, *.BMP, NULL, NULL,位图文件(*.BMP)|*.bmp;*.BMP|); if (IDOK = () / 加载位图并显示之 CDib dib; if (dib.Load() CClientDC dc(this); dib.SetPalette(&dc); dib.Draw(&dc); DIB位图父菜单下标记子菜单的单击事件消息处理函数为(其功能为给位图加上天极网logo): void CBitMapExampleDlg:OnMarkDibpic() / 弹出文件对话框,让用户选择标记logo C (TRUE, *.BMP, NULL, NULL, 标记位图文件(*.BMP)|*.bmp;*.BMP|); if (IDOK = () / 加载标记logo位图并与目标位图相与 CDib dib; if (dib.Load() CClientDC dc(this); dib.SetPalette(&dc); dib.Draw(&dc, 0, 0, - 1, - 1, SRCAND); 第 14 页