今までVC++で開発してきたアプリケーションの2Dの描画は通常のGDIを使っていたのですが、どうやらGDI+はアンチエイリアスができる、キャップスタイルを指定できるなど、かなり高機能で良さそうだということで、ここしばらくGDI+への切り替え作業を行っていました。でも、ドキュメントが少なくて苦労が多かったです。サンプルコードはC#やVBばかりなのも悲しい。
とりあえずMSDNを参考に試行錯誤してました。
http://msdn2.microsoft.com/en-us/library/ms533798%28VS.85%29.aspx
で、散々に苦労したのが文字の扱い。従来のGDIとGDI+では文字の描画結果が一致しなくて、位置を正確に制御するのがとても困難です。
ネット上でもいろいろ問題の指摘は見つかるものの、解決策を見つけるまでに数時間を費やしてしまいました。
結局、Gdiplus::bitmap 上であっても、GDIで描画する方法がわかったので、以下のようなコードで解決しました。
いわゆる、バッドノウハウだなぁ。
以下、参考までに。
Gdiplus::Bitmap *bmp; Gdiplus::Graphics g(bmp); HDC hdc = g.GetHDC(); CDC *pDC = CDC::FromHandle(hdc); pDC->TextOut(100, 100, L"Hello"); g.ReleaseHDC(hdc);
追記: Gdiplus::Bitmap で作成した描画結果を印刷しようとしたところ、うまくいかない。。どうやら次のコードでは画面描画はできても印刷はできないようでした。
Gdiplus::Graphics g(*pDC); g.DrawImage(&bitmap, 0,0,w,h)
で、結局StretchDIBitsを使って解決。
Gdiplus::BitmapData bitmapData; bitmap.LockBits(&Gdiplus::Rect(0,0,bitmap.GetWidth(), bitmap.GetHeight()) ,Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeWrite, PixelFormat24bppRGB, &bitmapData); RGBTRIPLE* pData; pData = (RGBTRIPLE*)bitmapData.Scan0; BITMAPINFO bmpInfo; bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = bitmap.GetWidth(); bmpInfo.bmiHeader.biHeight = bitmap.GetHeight(); bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = 24; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biClrUsed = 0; bmpInfo.bmiHeader.biClrImportant = 0; int lineNum = ::StretchDIBits(pDC->GetSafeHdc(), 0, 0, w, h, 0, h, w, -h, pData, &bmpInfo, DIB_RGB_COLORS, SRCCOPY);
と、思ったけれどしっかり実装しようとすると、次のURLの記述のようになるらしい。。大変だ。。
http://hp.vector.co.jp/authors/VA014436/prg_memo/windows/vcbasic/050.html
追記2: Gdiplus::Bitmap の FromFile で読み込んだ後で LockBits を行うと、GIF形式の時だけ失敗する。。よくわからない問題はまだまだ続くようです。