图形与图像编程(一)-图形编程

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





























猜你喜欢

转载自blog.csdn.net/greless/article/details/77719510