GDIPlus非典型误用一例

GDIPlus非典型误用一例

// ** 初始化GDI+
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
// ** 该成员变量用来保存GDI+被初始化后在应用程序中的GDI+标识。
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

Image  image( imagePath );          //加载图片
Graphics imageGraphics(&image);              //通过Image对象创建一个绘图句柄,使用这个句柄对图片进行操作 
imageGraphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
WCHAR string[ ] = L"Wishful Thinking";                   //要写的字
FontFamily fontFamily(L"Calibri"); 
Gdiplus::Font myFont(&fontFamily, 6, FontStyleRegular, UnitPoint); //第二个是字体大小
//SolidBrush blackBrush(Color(255, 0, 0, 0));  //半透明+文字RGB颜色
SolidBrush whiteBrush(Color(255, 255, 255, 255));  //半透明+文字RGB颜色
PointF school_site((REAL)300, (REAL)100);//文字放置的像素坐标
StringFormat format;                         
format.SetAlignment(StringAlignmentNear);    //文本排列方式,即在对应位置居中、靠左、靠右
//wcscpy_s(string, CT2CW(str));              //如果使用MFC中的CString,需要这样转换成WCHAR
imageGraphics.DrawString(string, wcslen(string), &myFont, school_site, &format, &whiteBrush     );//把string绘制到图上
CLSID pngClsid; 
GetEncoderClsid( L"image/jpeg", &pngClsid); 
imagePath.Replace(_T(".jpg"), _T("-note.jpg"));
image.Save(imagePath, &pngClsid, NULL );//保存添加了汉字的图像

// ** 卸载GDI+
Gdiplus::GdiplusShutdown(gdiplusToken);

先看这段典型的GDI+代码,似乎是没有什么问题。把这段代码放在一个main函数中编译可以正确运行,但如果将这段代码放到一个函数中被调用时却会出现崩溃。

跟踪了一下,调试时bug很容易发现,但平时却是不被人注意的,所以有必要记录一下,避免下次掉在同一个坑里。

注意: 最后卸载GDI+后,image对象其实并没有被析构。当image对象无效析构时会用到GDI+资源,但此时GDI+时已经被卸载所以程序会崩溃。

总结:对于这类需要使用时需要先加载、用完要卸载的类库,最好利用c++简单封装一下,利用类特性进行管理资源。

封装GDI+很简单,就不把代码贴上来了。