GDI 总结二: 位图的绘制

来源:互联网 发布:mac电脑渲染卡顿 编辑:程序博客网 时间:2024/05/21 11:06

         在GDI有一个特点: 就是所有的图片绘制,都是通过DC来完成的。DC之间是可以相互传递的。

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

         无论                 

                        位图--->屏幕

                        位图--->位图

                        屏幕---->位图

                        屏幕----->屏幕

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

       

 其关键点便是:

如何获得各自的DC

 

        对于屏幕:

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

                          ::GetDC() 返回的是CDC* 

                      

        对于图片:

                        CBitmap  不支持DC

                        CImage   获得DC

CImage img;img.Load(imageFilePath);CDC *pDC;pDC=CDC::FromHandle(img.GetDC());// use  pDC hereimg.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

如下例:

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 位图--->屏幕

// 位图到屏幕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类对象

// 位图到位图// 因为目的地是位图,所以先创建一个空白位图// 因为是位图与位图之间的传递,所以可以使用两个内存DC来完成// 两个DC如何兼容? 只要每一个DC都与屏幕DC兼容,则这两个DC也就互相兼容了CBitmap destBmp;CBitmap sourceBmp;BITMAP bm;// 定义源DC  与目的DC对象CDC  sourceDC;CDC  destDC;// 获得兼容的屏幕DCCDC *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类

 

// 位图到位图 2// 源位图为CImage对象,直接使用CImage对象的成员函数进行传递CImage sourceImage;CBitmap destBmp;CDC destDC;sourceImage.Load(imageFile);// 获得CImage对象的DCCDC *pDC=CDC::FromHandle(sourceImage.GetDC());// 创建Dest位图资源  DestDCdestDC.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 屏幕到位图          

//屏幕到位图CBitmap destBmp;CDC  destDC;// 获得兼容的屏幕DCCDC *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);