我需要在给定Graphics
引用的任何设备上画一条长1英寸的线。无论Transform
设置为什么,我都需要一英寸长。假设变换的缩放因子由scale
在水平和垂直方向上给出。
一些C++/CLI代码:
g->DrawLine(Pens::Black, 50.0f, 50.0f, 50.0f + oneInchEquivalent / scale, 50.0f);
现在,这一点都不困难!现在,我们需要做的就是计算
oneInchEquivalent
。g->DpiX
给我的距离是屏幕上看起来只有一英寸,但打印机上却没有。看来,在打印机上,将g->PageUnit
设置为GraphicsUnit::Display绘制一条100单位的线会给我一行一英寸长的线。但是,无论PageUnit
设置如何,我确实都需要此功能。实际上,更改PageUnit
会改变笔的宽度!!编辑:我已经在这里暂时接受了唯一的答案,因为它与我要寻找的非常接近。
最佳答案
经过几次编辑后答案变得相当长,所以这是最终结果:
将PageUnit
对象的Graphics
属性设置为GraphicsUnit.Pixel
并使用DpiX和DpiY值乘以坐标将在显示设备和打印机设备上呈现预期的结果。
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;
}
您可以将其绘制在窗体(或某些控件)上:
using (Graphics g = this.CreateGraphics())
{
Point start = new Point(1, 1);
Point end = new Point(2, 1);
DrawInchLine(g, Color.Black, start, end);
}
...或将输出发送到打印机:
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
。