【发布时间】:2011-01-19 13:35:33
【问题描述】:
我在同时使用 GDI 和 GDI+ 进行绘图时遇到问题。页面转换——尤其是缩放——似乎在两者之间有点偏离。除了SetViewportExt 和SetWindowExt 之外,GDI 上下文的哪些属性会影响输出的缩放?
代码几乎只使用 GDI 进行绘图,但在少数需要其特性(半透明)的情况下使用 GDI+。它使用SetViewportExt、SetWindowExt 和SetViewportOrg 来启用缩放和滚动。
当需要 GDI+ 时,我在 HDC 周围构造一个 Gdiplus::Graphics 对象并进行绘图。我假设这会使图形上下文包装设备上下文并将其渲染传递给设备上下文。如果我提取 GDI+ 图形上下文的变换矩阵,我看到它是单位矩阵,所以缩放是在其他地方完成的(我猜是在设备上下文中)。
我设计了一个简单的测试,我用 GDI 和 GDI+ 绘制相同的矩形数组,以确保在这两种情况下所有的转换都是相同的。代码sn-p如下:
CRect rect = ...;
// Draw the rectangle using GDI
CPen cpen(PS_DASH, 0, RGB(0,0,255));
pDC->SelectObject(&cpen);
pDC->Rectangle(rect);
{
// Draw the rectangle using GDI+
Gdiplus::Graphics graphics(pDC->m_hDC);
Gdiplus::Pen pen(Gdiplus::Color(180,180,180));
graphics.DrawRectangle(
&pen,
Gdiplus::Rect(rect.left, rect.top, rect.Width(), rect.Height()));
}
结果在这里:(蓝色虚线是GDI画的,灰色是GDI+画的)
我可以清楚地看到两个坐标系是不同的。我预计会有一些舍入误差,但不是这里看到的缩放误差。此外,当我更改缩放系数时,GDI+ 根据缩放在两个方向上跳跃±4 像素左右。这也在屏幕截图中突出显示,因为与 GDI 矩形相比,GDI+ 矩形在 X 轴上具有正偏移,在 Y 轴上具有负偏移。
有人知道这里发生了什么吗?
我将如何着手调查/调试此问题?这发生在 Windows 的内部,所以很遗憾我无法调试它。
作为参考,这是我的 viewport/window org/ext 的样子:
Window Ext: (134000, 80500)
Window Org: (0, 0)
Viewport Ext: (1452 872)
Viewport Org: (35 35)
更新:
我已经解决了这个问题,但它并不漂亮。基本做法是:
在屏幕空间中获取两个坐标(原点和第二个适当的点),并使用 GDI(
DPtoLP函数)将它们转换为逻辑坐标。将 GDI 转换重置为
MM_TEXT。使用变换后的点为 GDI+ 构造一个变换矩阵,代表相同的变换
最后使用这个矩阵构造一个具有正确转换的 GDI+ 上下文。
这有点小技巧,但它确实有效。不过,我仍然不知道为什么两者之间存在差异。至少它表明可能有一个 GDI+ 上下文模仿 GDI 转换。
【问题讨论】: