GDI和GDI+对象的相互转换 作者:dotLive
当然希望可以使用GDI+来完全代替GDI,再不济也只需要从GDI对象转到GDI+对象。但是就是有那么些半吊子的工程,又要新技术新特性、又希望快速开发、又不肯丢弃旧版本的已有的功能。没办法,只能打补丁。石头、剪子、不......
1.CDC 到 Graphics 只要这样:
Graphics g(pDC
->
GetSafeHdc());
//
只要能构造CDC句柄的MFC对象都可以
//
CClientDC、CPaintDC,也都可以
2.CBitmap到 Graphics 需要创建一个内存位图设备:
CDC MemDC; CBitmap MemBitmap; MemDC.CreateCompatibleDC(pDC); MemBitmap.CreateCompatibleBitmap(pDC,size.cx, size.cy); CBitmap
*
pOldBit
=
MemDC.SelectObject(
&
MemBitmap); Graphics g(MemDC.GetSafeHdc());
/// … you can work with GDI+ … ///
或者使用:
Bitmap::Bitmap(HBITMAP,HPALETTE)
以及
static
Bitmap
*
FromHBITMAP(HBITMAP hbm,HPALETTE hpal)
3.想要用 Bitmap 来打开图片,却又需要用 GDI 的绘图函数来操作(一般都为历史遗留问题),就需要将 Bitmap 对象转换到 CBitmap ,可以这样:
Bitmap
*
pPicture
=
new
Bitmap(L
"
dotLive.jpg
"
); HBITMAP hBitmap; CBitmap
*
pbm; pPicture
->
GetHBITMAP(Color(
0
,
0
,
0
),
&
hBitmap); pbm
=
CBitmap::FromHandle(aaa1);
/// … use pbm to do the GDI works ///
pbm
->
DeleteObject();
//
要记得删除GDI对象,否则你会发现你的内存占用…
CView使用OnPaint打印图像就是一个例子,使用GDI+无法在打印纸上打印出图像,只有一片空白。在找到原因之前,只好从GDI+转换到GDI使用BitBlt和StretchBlt方式来打印。
4.保存 Bitmap ,打开很方便,保存就不那么的方便了。 Bitmap 或者 Image 打开图像会自动锁定文件,保存时会产生文件被使用之类的错误。一种折衷的办法是,保存时全新创建一个 Bitmap ( Image )对象,将原来的对象画到新对象上,然后将原来的对象删除以释放文件。保存新对象。不能用 clone ,它会将锁定的文件资源一块复制过来,则解锁文件需要的释放对象就又多了一个。
Bitmap
*
tPic
=
new
Bitmap(L
"
dotLive.jpg
"
);
//
锁定文件
Bitmap
*
pPicture
=
new
Bitmap(tPic
->
GetWidth() ,tPic
->
GetHeight() ,tPic
->
GetPixelFormat()); Graphics g(pPicture); g.DrawImage(tPic,
0
,
0
,m_nWidth,m_nHeight);
//
复制过来
delete tPic;
//
解锁
/// … use the pPicture to access "dotLive.jpg" … ///
CLSID tiffClsid; GetEncoderClsid(L
"
image/jpeg
"
,
&
tiffClsid);
//
这个函数MSDN中有
pPicture
->
Save(L
"
dotLive.jpg
"
,
&
tiffClsid);
//
保存
5.Graphics 到 HDC ,想要用 Bitmap 方便打开图像,又要往图像里写文字作图等。糟糕的是由于历史遗留问题,这些操作都是使用 GDI 完成的。并且 GDI+ 没有异或绘图模式(实现橡皮筋效果)、没有文字输出底色不透明、字符串需要转换到 WChar 。咋办呢,可以这样转:
Bitmap
*
pPicture
=
new
Bitmap(L
"
dotLive.jpg
"
);
//
打开图片
Graphics tempG(pPicture ); HDC hdc
=
tempG.GetHDC ();
//
获得GDI句柄
CDC
*
tempDC
=
CDC::FromHandle(hdc);
/// … hurry up, draw what you want … ///
tempG.ReleaseHDC(hdc);
//
要记得relese,GDI都需要释放,否则资源会被占用而不接受其他操作
转贴来源:
http://www.cnblogs.com/dotLive/archive/2006/08/25/486588.html