最近在用GDI+重写一个示波器控件(Oscilloscope Control),原因是这个控件是用WTL写的,无法兼容于MFC的主界面程序。期间看到一个使用GDI+的双缓冲(Double buffering)解决方案:
01 RECT rc;
02 this->GetClientRect(&rc);
03
04 Bitmap bmp(rc.right, rc.bottom, PixelFormat32bppARGB);
05 Graphics* graph = Graphics::FromImage(&bmp);
06
07 Pen pen(Color(255, 0, 0, 255));
08 SolidBrush brush(Color(255, 0, 0, 255));
09 FontFamily ff(L"微软雅黑");
10 Font f(&ff, 28, FontStyleRegular, UnitPixel);
11 PointF pf(rc.left+5, rc.top+5);
12
13 graph->DrawString(L"GDI+ 示例程序", -1, &f, pf, &brush);
14
15 Graphics graphics(lpDrawItemStruct->hDC);
16 graphics.DrawImage(&bmp, 0, 0);
也就是先在Bitmap中使用Graphics进行绘图,绘图完毕后再一次性绘制到HDC上。
但是我发现设计到字符串的输出的时候,直接将字符串输出到HDC上 与先绘制到Bitmap上再使用DrawImage将Bitmap输出到HDC 这两种方法有非常大的差别,如下两图:
[](/img/original.png) |
直接DrawString到HDC |
[](/img/beforeAntialias.png) |
先Bitmap再DrawImage到HDC |
后者的锯齿严重,后来在stackoverflow.com上找到这个解决方案:[Antialiased text on transparent bitmap](http://stackoverflow.com/questions/1291061/antialiased-text-on-transparent-bitmap)。遂将代码修改为:
01 RECT rc;
02 this->GetClientRect(&rc);
03
04 Bitmap bmp(rc.right, rc.bottom, PixelFormat32bppARGB);
05 Graphics* graph = Graphics::FromImage(&bmp);
06
07
08 Pen pen(Color(255, 0, 0, 255));
09 SolidBrush brush(Color(255, 0, 0, 255));
10 FontFamily ff(L"微软雅黑");
11 Font f(&ff, 28, FontStyleRegular, UnitPixel);
12 PointF pf(rc.left+5, rc.top+5);
13
14 graph->SetTextRenderingHint(TextRenderingHintAntiAlias);
15 graph->DrawString(L"GDI+ 示例程序", -1, &f, pf, &brush);
16
17 Graphics graphics(lpDrawItemStruct->hDC);
18 graphics.DrawImage(&bmp, 0, 0);
效果有非常大的改观:
[](/img/afterAntialias.png) |
指定文本输出质量之后 |