GDI C++ 位图的绘制
2018-03-06 14:06
519 查看
在GDI有一个特点: 就是所有的图片绘制,都是通过DC来完成的。DC之间是可以相互传递的。
两个DC之中的图形 通过DC--->DC 来相互传递信息。
无论
位图--->屏幕
位图--->位图
屏幕---->位图
屏幕----->屏幕
他们所使用的都是DC-->DC之间的传递。
其关键点便是:
如何获得各自的DC
对于屏幕:
直接使用GetDC() ReleaseDC() 便可
::GetDC() 返回的是CDC*
对于图片:
CBitmap 不支持DC
CImage 获得DC
[cpp] view
plaincopyprint?
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
plaincopyprint?
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
plaincopyprint?
// 位图到屏幕
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
plaincopyprint?
// 位图到位图
// 因为目的地是位图,所以先创建一个空白位图
// 因为是位图与位图之间的传递,所以可以使用两个内存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
plaincopyprint?
// 位图到位图 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
plaincopyprint?
//屏幕到位图
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);
两个DC之中的图形 通过DC--->DC 来相互传递信息。
无论
位图--->屏幕
位图--->位图
屏幕---->位图
屏幕----->屏幕
他们所使用的都是DC-->DC之间的传递。
其关键点便是:
如何获得各自的DC
对于屏幕:
直接使用GetDC() ReleaseDC() 便可
::GetDC() 返回的是CDC*
对于图片:
CBitmap 不支持DC
CImage 获得DC
[cpp] view
plaincopyprint?
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
plaincopyprint?
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
plaincopyprint?
// 位图到屏幕
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
plaincopyprint?
// 位图到位图
// 因为目的地是位图,所以先创建一个空白位图
// 因为是位图与位图之间的传递,所以可以使用两个内存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
plaincopyprint?
// 位图到位图 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
plaincopyprint?
//屏幕到位图
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);
相关文章推荐
- 使用C++绘制GDI位图的基本编写实例
- 【备忘】GDI位图绘制四部曲
- c++ GDI绘图 利用SetROP2函数的R2_NOT与R2_NOTXORPEN属性,重新绘制时清除原先的图
- GDI C++(2) 位图的绘制
- GDI之绘制位图
- Delphi GDI对象之绘制位图
- GDI的 点 线 面 双缓冲 位图的绘制
- GDI对位图的绘制
- GDI 总结二: 位图的绘制
- GDI绘制透明位图
- Delphi GDI对象之绘制位图
- 利用c++实现数值坐标刻度生成,并利用GDI绘制
- GDI 总结二: 位图的绘制
- HGE使用GDI绘制中文字体
- 在SurfaceView/自定义View中利用手势绘制不同颜色不同形状的图形并且保存为Bitmap位图
- C# GDI+绘制行情系统 —— 行情Listview功能分析(1)
- C++Directx11开发笔记三:绘制图形
- 【笨嘴拙舌WINDOWS】GDI绘制区域
- C++ GDI+ Region区域
- C++/GDI+ 取得照片的拍照时间