GDI +:如何在绘制的任何设备上绘制长度为1英寸的线?
在需要引用 Graphics
的任何设备上,我都需要在其上画一条长1英寸的线。无论将 Transform
设置为什么,我都需要一英寸长。假定变换的缩放因子由水平和垂直方向上的 scale
给出。
I need to draw a line one inch long on any device given a Graphics
reference to it. I need it to be an inch long regardless of what Transform
is set to. Let's assume that the scaling factor of the transform is given by scale
in both horizontal and vertical directions.
某些C ++ / CLI代码:
Some C++/CLI code:
g->DrawLine(Pens::Black, 50.0f, 50.0f, 50.0f + oneInchEquivalent / scale, 50.0f);
现在,这一点都不困难!现在我们要做的就是计算 oneInchEquivalent
。
Now that was not difficult at all! Now all we need to do is calculate oneInchEquivalent
.
g-> DpiX
给我的距离在屏幕上看起来像一英寸,但在打印机上却没有。看来在打印机上,如果将 g-> PageUnit
设置为GraphicsUnit :: Display绘制一条100单位的线,则会给我一行一英寸长的线。但是,无论 PageUnit
设置如何,我确实都需要使用它。实际上,更改 PageUnit
会改变笔的宽度!
g->DpiX
gives me a distance of what looks like one inch on screen but not on the printer. It seems that on printers, drawing a line of 100 units with g->PageUnit
set to GraphicsUnit::Display will give me a line one inch long. But, I really need this to work regardless of the PageUnit
setting. In fact, changing PageUnit
will change the width of the pen!!
编辑:我暂时接受了这里的唯一答案,因为它与我要寻找的非常接近。
I have tentatively accepted the only answer here as it's pretty close to what I am looking for.
答案很长经过几次编辑后,最终结果如下:
The answer became rather long after a couple of edits, so here is the final result:
设置 PageUnit 属性$ c> Graphics 指向 GraphicsUnit.Pixel
的对象,并将坐标与DpiX和DpiY值相乘将在显示和打印机上呈现预期结果
Setting the PageUnit
property of the Graphics
object to GraphicsUnit.Pixel
and taking in multiplying coordinates with the DpiX and DpiY values will render the expected result on both display and printer devices.
private static void DrawInchLine(Graphics g, Color color, Point start, Point end)
{
GraphicsUnit originalUnit = g.PageUnit;
g.PageUnit = GraphicsUnit.Pixel;
using (Pen pen = new Pen(color, 1))
{
g.DrawLine(pen,
start.X * g.DpiX,
start.Y * g.DpiY,
end.X * g.DpiX,
end.Y * g.DpiY);
}
g.PageUnit = originalUnit;
}
您可以将其绘制在窗体(或某些控件)上:
You can have it paint on a Form (or some control):
using (Graphics g = this.CreateGraphics())
{
Point start = new Point(1, 1);
Point end = new Point(2, 1);
DrawInchLine(g, Color.Black, start, end);
}
...或将输出发送到打印机:
...or send the output to a printer:
PrintDialog dialog = new PrintDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
PrintDocument pd = new PrintDocument();
pd.PrinterSettings = dialog.PrinterSettings;
pd.PrintPage += (psender, pe) =>
{
Point start = new Point(1, 1);
Point end = new Point(2, 1);
DrawInchLine(pe.Graphics, Color.Black, start, end);
pe.HasMorePages = false;
};
pd.Print();
}
但是,这确实取决于设置 PageUnit
。
This does, however, rely on setting the PageUnit
.