您的位置:首页 > 其它

GDI 总结二: 位图的绘制

2014-11-12 13:31 267 查看
在GDI有一个特点: 就是所有的图片绘制,都是通过DC来完成的。DC之间是可以相互传递的。

两个DC之中的图形 通过DC--->DC 来相互传递信息。

无论

位图--->屏幕

位图--->位图

屏幕---->位图

屏幕----->屏幕

他们所使用的都是DC-->DC之间的传递。

其关键点便是:

如何获得各自的DC

对于屏幕:

直接使用GetDC() ReleaseDC() 便可

::GetDC() 返回的是CDC*

对于图片:

CBitmap 不支持DC

CImage 获得DC

[cpp] view
plaincopy

CImage img;

img.Load(imageFilePath);

CDC *pDC;

pDC=CDC::FromHandle(img.GetDC());

// use pDC here

img.ReleaseDC();

注意:

::GetDC() 返回的是CDC*

而CImage::GetDC() 返回的HDC

对图像进行操作

::GetDC() 所获得的是屏幕的DC, 使用此DC ,可以对屏幕进行绘图。

如果我们想在某一个位图的基础上,再次绘图的话,便不能简单的使用::GetDC()了,因为它只是负责在屏幕上绘图。

那怎么办呢?

既然所有的绘图都是在DC上进行绘图,所以我们必须把这个位图选择进DC,这样对DC操作,就相当直接对位图进行操作

pDC->SelectObject(&bmp):

// use pDC to draw orthers in the bmp

构造内存DC

一般我们为了避免闪烁等现象,需要构造内存DC ,然后再DC上进行绘制,绘制完毕后,通过DC之间的传递,将图像再绘制到屏幕中去。

CDC memDC; 只是创建了一个CDC对象,还没有创建DC资源

memDC.CreateCompatibleDC(pDC); 才是真正创建DC资源。

创建兼容DC是关键,其关键之处在于要创建的DC与哪个现有的DC兼容。

因为内存DC只是个中介,它必须要将其DC中的图像传递到其它DC中(目的DC),才会体现其价值。

而DC 与 DC之间可以传递信息的前提是:两DC是兼容的。

据此可知: 内存DC要兼容目的DC

如下例:

[cpp] view
plaincopy

CBitmap bmp;

bmp.LoadBitmap(IDI_BITMAP);

CDC memDC;

memDC.CreateCompatibleDC(pDC);

memDC.SelectObject(&bmp);

pDC->BitBlt(0,0,nWidth,nHeight,&memDC,0,0,SRCCOPY);

DC--->DC的传递

下面针对各种情况一一给出示例:

1 位图--->屏幕

[cpp] view
plaincopy

// 位图到屏幕

CBitmap bmp;

BITMAP bm;

CDC memDC;

CDC *pDC=GetDC();

//加载图片 获得图片信息

bmp.LoadBitmap(IDB_BITMAP);

bmp.GetBitmap(&bm);

// 创建与屏幕兼容的DC,并选入位图

memDC.CreateCompatibleDC(pDC);

CBitmap* pOldBmp=(CBitmap *)memDC.SelectObject(&bmp);

// 将位图绘制在屏幕中 位图--->屏幕

pDC->SetStretchBltMode(COLORONCOLOR);

pDC->StretchBlt(0,0,100,100,&memDC,bm.bmWidth,bm.bmHeight,SRCCOPY);

memDC.SelectObject(pOldBmp);

//释放资源

ReleaseDC(pDC);

2

位图到位图1-----二者都是CBitmap类对象

[cpp] view
plaincopy

// 位图到位图

// 因为目的地是位图,所以先创建一个空白位图

// 因为是位图与位图之间的传递,所以可以使用两个内存DC来完成

// 两个DC如何兼容? 只要每一个DC都与屏幕DC兼容,则这两个DC也就互相兼容了

CBitmap destBmp;

CBitmap sourceBmp;

BITMAP bm;

// 定义源DC 与目的DC对象

CDC sourceDC;

CDC destDC;

// 获得兼容的屏幕DC

CDC *pDC=GetDC();

//加载源图片

sourceBmp.LoadBitmap(IDB_BITMAP);

sourceBmp.GetBitmap(&bm);

// 创建源DC资源

sourceDC.CreateCompatibleDC(pDC);

sourceDC.SelectObject(&sourceBmp);

// 创建Dest位图资源

destBmp.CreateCompatibleBitmap(pDC,bm.bmWidth,bm.bmHeight);

// 创建DestDC资源

destDC.CreateCompatibleDC(pDC);

destDC.SelectObject(&destBmp);

//位图到位图传递

destDC.SetStretchBltMode(HALFTONE);

destDC.StretchBlt(0,0,bm.bmWidth,bm.bmHeight,&sourceDC,0,0,100,100,SRCCOPY);

ReleaseDC(pDC);

位图到位图2---源位图为CImage类

[cpp] view
plaincopy

// 位图到位图 2

// 源位图为CImage对象,直接使用CImage对象的成员函数进行传递

CImage sourceImage;

CBitmap destBmp;

CDC destDC;

sourceImage.Load(imageFile);

// 获得CImage对象的DC

CDC *pDC=CDC::FromHandle(sourceImage.GetDC());

// 创建Dest位图资源 DestDC

destDC.CreateCompatibleDC(pDC);

destDC.SelectObject(&destBmp);

::SetStretchBltMode(destDC.m_hDC,HALFTONE);

::SetBrushOrgEx(destDC.m_hDC,0,0,NULL);

// 直接使用CImage成员函数进行传递 其实是:CImage封装了DC之间的传递工作

sourceImage.StretchBlt(&destDC,CRect(0,0,100,100),CRect(0,0,100,100),SRCCOPY);

// 释放DC资源

sourceImage.ReleaseDC();

3 屏幕到位图

[cpp] view
plaincopy

//屏幕到位图

CBitmap destBmp;

CDC destDC;

// 获得兼容的屏幕DC

CDC *pDC=GetDC();

// 创建Dest位图资源

destBmp.CreateCompatibleBitmap(pDC,100,100);

// 创建DestDC资源

destDC.CreateCompatibleDC(pDC);

destDC.SelectObject(&destBmp);

//屏幕到位图传递

destDC.SetStretchBltMode(HALFTONE);

destDC.StretchBlt(0,0,100,100,pDC,0,0,100,100,SRCCOPY);

ReleaseDC(pDC);

转自:http://blog.csdn.net/shuilan0066/article/details/7086897
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图形图像