DDB和DIB的区别
可以這樣理解 DDB 只存在與內存裡,它是與當前顯示相關的,也不可能保存成文件。
一般情況下用 CreateBitmap , CreateCompliateBitmap 就是 DDB
而用 CreateDIBSection 得到的就是 DIB, DIB 是文件相關,而 DDB 是設備相關。
但在顯示時 DDB 要比 DIB 快。
而 bmp 文件是 DIB
一、设备相关位图DDB
DDB(Device-Dependent Bitmaps)设备相关位图,使用BITMAP结构表示。此结构的成员使用像素指定矩形区域的宽度和高度,宽度数组从设备调色板转换成像素,并通过颜色面板和颜色位值指定
设备的颜色格式。程序可以通过GetDeviceCaps函数和相应的常数获取设备的颜色格式。
设备相关位图分为两种:可废弃的DDB和不可废弃的DDB。如果位图没有载入设备上下文和系统内存比较低,系统会丢弃可废弃的设备相关位图。使用CreateDiscardableBitmap()函数可以创建可废弃设备相关位图。使用CreateBitmap、CreateCompatiblemap、CreateBitmapIndirect可以创建不可废弃的设备相关位图。
typedef struct tagBITMAP{
LONG bmType;指定位图的类型,此成员必须为0
LONG bmWidth;//指定位图的宽度,单位是像素
LONG bmHeight;//指定位图的高度,单位是像素
LONG bmWidthBytes;//指定每个扫描行的字节数目
WORD bmPlanes;//指定颜色面板的个数
WORD bmBitsPixel;//指定表示像素的颜色需要的位数
LPVOID bmBits;//指定位图位值得位值指针,此成员必须是字符数组的长指针
}BITMAP;
二、设备无关位图DIB
DIB(Deveice-Independent Bitmaps)设备无关位图,是包含一个与设备无关的颜色表的位图。颜色表描述像素值如何与RGB颜色值对应。RGB是通过光描述颜色的模型,表示颜色占有的R G B的比例。一个设备无关位图包含下列颜色的大小信息。创建矩形图像的设备的颜色格式
创建矩形图像的设备的方法
创建矩形图像的设备的调色板
映射矩形图像的RGB三色像素数组
如果对图像进行压缩,还包括数据压缩方案
这些颜色和大小信息存储在BITMAPINFO结构中
typedef struct tagBITMAPINFO
{
BITMAPINFOHEADER bmiHeader;//指定了一个BITMAPINFOHEADER结构,包含了有关设备相关位图的度量和颜色格式的信息。
RGBQUAD bmiColors[1];//指定了一个RGBQUAD或DWORD数据类型的数组,定义了位图中的颜色。
} BITMAPINFO;
三、实例
// 画刷绘图实例
void CGDISampleView::OnMenuitemBrush()
{
CDC* pDC = GetDC();
CBrush newBrush;
if( newBrush.CreateSolidBrush(RGB(0,255,0)))
{
RECT rect;
GetClientRect(&rect);
CRgn rgn;
rgn.CreateEllipticRgn(rect.left+10,rect.top, rect.right-10,rect.bottom);
pDC->FillRgn(&rgn, &newBrush);
}
else
MessageBox("创建画刷失败!");
}
// 画笔绘图实例
void CGDISampleView::OnMenuitemPen()
{
CDC* pDC = GetDC();
CPen newPen;
if( newPen.CreatePen( PS_SOLID, 2, RGB(255,0,0) ) )
{
CPen* pOldPen = pDC->SelectObject( &newPen );
RECT rect;
GetClientRect(&rect);
pDC->MoveTo(rect.left, rect.top);
pDC->LineTo(rect.right, rect.bottom);
pDC->SelectObject( pOldPen );
}
else
MessageBox("创建画笔失败!");
}
// 位图实例
void CGDISampleView::OnMenuitemBitmap()
{
CBitmap bitmap;
CDC *pDC = GetDC();
bitmap.LoadBitmap(IDB_BITMAP_FACE);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(&bitmap);
BITMAP bmp;
bitmap.GetBitmap(&bmp);
CRect rect;
GetClientRect(&rect);
pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &memDC,
0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
memDC.DeleteDC();
::DeleteObject(&bitmap);
}
// 区域实例
void CGDISampleView::OnMenuitemRegion()
{
CDlgEllip dlg;
dlg.DoModal();
}
BOOL CDlgEllip::OnInitDialog()
{
CDialog::OnInitDialog();
SetWindowText(_T("椭圆窗口测试"));
CWnd* hParent = this->GetParent();
CenterWindow(hParent);
CRect rect;
this->GetClientRect(&rect);
int nEllipseWidth = rect.Width();
int nEllipseHeight = rect.Height();
m_rgnWnd.CreateEllipticRgn(0, 0, nEllipseWidth, nEllipseHeight);
SetWindowRgn((HRGN)m_rgnWnd, TRUE); // 将m_rgnWnd设置为窗口区域
return TRUE;
}