3

无论图形转换矩阵的比例如何,我都需要创建一个宽度为 0.5 毫米的笔。这是我正在做的事情:

注意:示例代码是 C++/CLI,但欢迎使用 C# 回答。

// assume that g is a Graphics object
int dpi = g->DpiX;
float dotsPerHalfInch = dpi * 0.5;

// to extract scale factor from the transformation matrix...
// create two points distant one unit apart...
array<PointF> ^points = gcnew array<PointF>{
    PointF(0.0f, 0.0f), PointF(1.0f, 0.0f)
};

// transform them...
g->Transform->TransformPoints(points);

// get distance after transformation...
float dX = points[1].X - points[0].X;
float dY = points[1].Y - points[0].Y;
float distance = Math::Sqrt(dX * dX + dY * dY);

// reverse the effects of any scale factor in graphics transform
float penWidth = dotsPerHalfInch / distance;

Pen ^halfInchPen = gcnew Pen(Color::Black, penWidth);

似乎在屏幕上不起作用(96 dpi)......给了我一支像素宽的笔。在 PDF 打印机 (600 dpi) 上,它给了我一支比半英寸厚得多的笔。

我究竟做错了什么?在 GDI 中创建非缩放笔的正确方法是什么?

4

3 回答 3

6

Pen 本身有一个 Transform 属性。在图形对象上使用与全局比例变换相反的那个。将笔宽设置为您想要的任何常量。

gdi+ 中还有一个错误,使宽度<1.5 的笔无法缩放。

好链接:https ://web.archive.org/web/20131221083258/http://bobpowell.net/scalepens.aspx

(图形对象上还有一个 PageUnit 属性,能够在像素、毫米等之间进行更改。不知道这是否有帮助)

于 2011-06-22T20:38:32.347 回答
0

我知道这是一篇超级老掉牙的帖子,但是我发现了一些关于缩放笔宽的有趣的东西,因为我现在正在努力这样做。

也许是因为我使用的是 .Net Core 3?无论如何,我 ScaleTransform'ed 和 TranslateTransform'ed 一个控件,以便我可以绘制不同比例的线条。到目前为止,一切都很好。但当然,正如大多数人所知,绘制的线宽也会被缩放,这通常是一种不良影响——线太粗了。

为了使线条保持在 1 像素,我看到了以下作为解决方案提供的解决方案(即,将 0f 添加到笔构造函数中的宽度参数:

            Pen penBlack0 = new Pen(Color.Black, 0f);
            sg.Graphics.DrawLine(penBlack0, 10, 20, 100, 50);

但这没有任何区别。画的线还是太粗了。此外,如果您在调试器中查看,笔的 Width 属性是 1,而不是零。但是,如果我这样做...

            Pen penBlack0 = new Pen(Color.Black);
            penBlack0.Width = 0f;
            sg.Graphics.DrawLine(penBlack0, 10, 20, 100, 50);

结果是绘制了正确的 1 像素线宽。

我不确定这样做有什么区别,或者为什么在构造函数中没有将 Width 属性设置为 0f 。

无论如何,这就是我克服这个障碍的方法。

于 2021-10-30T04:39:07.123 回答
0

惊人的。我们遇到了同样的问题,当在 ctor 中使用 0f 时工作正常,但在一些 Windows 更新笔开始使用缩放因子后,结果线变粗了。在 ctor 之外设置笔宽 - 解决了这个问题。

于 2021-11-05T18:34:20.717 回答