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; }