CDIB什么意思

CDIB什么意思,第1张

VC里的类

Visual C++ MFC中没有提供一个专门的类来处理DIB位图,因此,为了方便地使用位图文件键誉,我们有必要派生一个CDib类。类的源代码如下:

(1) CDib类的声明

// DIB.h:类CDib声枣伏明头文件

#ifndef __DIB_H__

#define __DIB_H__

#include <wingdi.h>

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 nHeight = -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_pDib = NULL

}

CDib::~CDib()

{

// 如果位图已经被加载,释放内存

if (m_pDib != NULL)

delete []m_pDib

}

下面这个函数非常重要,其功能为加载位图,类似于CBitmap类的LoadBitmap函数:

BOOL CDib::Load(const char *pszFilename)

{

CFile cf

// 打开位图文件

if (!cf.Open(pszFilename, CFile::modeRead))

return (FALSE)

// 获得位图文件大小凳亮携,并减去BITMAPFILEHEADER的长度

DWORD dwDibSize

dwDibSize = cf.GetLength() - sizeof(BITMAPFILEHEADER)

// 为DIB位图分配内存

unsigned char *pDib

pDib = new unsigned char[dwDibSize]

if (pDib == NULL)

return (FALSE)

BITMAPFILEHEADER BFH

// 读取位图文件数据

try

{

// 文件格式是否正确有效

if ( cf.Read(&BFH, sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER) ||

BFH.bfType != ’MB’ || cf.Read(pDib, dwDibSize) != dwDibSize)

{

delete []pDib

return (FALSE)

}

}

catch (CFileException *e)

{

e->Delete()

delete []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_pDib[sizeof(BITMAPINFOHEADER)]

// 计算调色板中实际颜色数量

m_nPaletteEntries = 1 <<m_pBIH->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_pDib[sizeof(BITMAPINFOHEADER) + m_nPaletteEntries * sizeof (RGBQUAD)]

// delete先前的调色板

if (m_Palette.GetSafeHandle() != NULL)

m_Palette.DeleteObject()

// 如果位图中存在调色板,创建LOGPALETTE 及CPalette

if (m_nPaletteEntries != 0)

{

LOGPALETTE *pLogPal = (LOGPALETTE*)new char[sizeof(LOGPALETTE) + m_nPaletteEntries *sizeof(PALETTEENTRY)]

if (pLogPal != NULL)

{

pLogPal->palVersion = 0x300

pLogPal->palNumEntries = m_nPaletteEntries

for (int i = 0i <m_nPaletteEntriesi++)

{

pLogPal->palPalEntry[i].peRed = m_pPalette[i].rgbRed

pLogPal->palPalEntry[i].peGreen = m_pPalette[i].rgbGreen

pLogPal->palPalEntry[i].peBlue = m_pPalette[i].rgbBlue

}

//创建CPalette并释放LOGPALETTE的内存

m_Palette.CreatePalette(pLogPal)

delete []pLogPal

}

}

return (TRUE)

}

//函数功能:保存位图入BMP文件

BOOL CDib::Save(const char *pszFilename)

{

if (m_pDib == NULL)

return (FALSE)

CFile cf

if (!cf.Open(pszFilename, CFile::modeCreate | CFile::modeWrite))

return (FALSE)

try

{

BITMAPFILEHEADER BFH

memset(&BFH, 0, sizeof(BITMAPFILEHEADER))

BFH.bfType = ’MB’

BFH.bfSize = sizeof(BITMAPFILEHEADER) + m_dwDibSize

BFH.bfOffBits = sizeof(BITMAPFILEHEADER) +

sizeof(BITMAPINFOHEADER) + m_nPaletteEntries *sizeof(RGBQUAD)

cf.Write(&BFH, sizeof(BITMAPFILEHEADER))

cf.Write(m_pDib, m_dwDibSize)

}

catch (CFileException *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)

// 获取位图宽度和高度赋值

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_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类的代码中我们可以看出,DIB位图的显示需遵循如下步骤:

(1)读取位图,本类中使用pDib = new unsigned char[dwDibSize]为位图中的信息分配内存,另一种方法是调用API函数CreateDIBSection,譬如:

m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(),

(LPBITMAPINFO) m_lpBMPHdr, DIB_RGB_COLORS,

(LPVOID*) &m_lpDIBits, NULL, 0)

m_hBitmap定义为:

HBITMAP m_hBitmap

(2)根据读取的位图信息,计算出调色板大小,然后创建调色板;

(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位图"父菜单下"打开"子菜单的单击事件消息处理函数为(其功能为打开位图并显示之):

void CBitMapExampleDlg::OnOpendibpic()

{

// d出文件对话框,让用户选择位图文件

CFileDialog fileDialog(TRUE, "*.BMP", NULL, NULL,"位图文件(*.BMP)|*.bmp*.BMP|")

if (IDOK == fileDialog.DoModal())

{

// 加载位图并显示之

CDib dib

if (dib.Load(fileDialog.GetPathName()))

{

CClientDC dc(this)

dib.SetPalette(&dc)

dib.Draw(&dc)

}

}

}

"DIB位图"父菜单下"标记"子菜单的单击事件消息处理函数为(其功能为给位图加上天极网logo):

void CBitMapExampleDlg::OnMarkDibpic()

{

// d出文件对话框,让用户选择标记logo

CFileDialog fileDialog(TRUE, "*.BMP", NULL, NULL, "标记位图文件(*.BMP)|*.bmp*.BMP|")

if (IDOK == fileDialog.DoModal())

{

// 加载标记logo位图并与目标位图相与

CDib dib

if (dib.Load(fileDialog.GetPathName()))

{

CClientDC dc(this)

dib.SetPalette(&dc)

dib.Draw(&dc, 0, 0, - 1, - 1, SRCAND)

}

}

VC++ 6.0 只要历碧 include Windows.h 链接启烂仿 Gdi32.lib 就应当悄纤有 有关的函数了。DIB 属 SDK 里的Windows GDI. 好像没有CDib。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/12317097.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存