GDI +:如何在任何设备上绘制一条长度为1英寸的线?

Agn*_*ian 12 .net graphics gdi+

我需要在任何给出Graphics参考的设备上绘制一英寸长的线.不管Transform设定的是什么,我都需要一英寸长.假设变换的缩放因子由scale水平和垂直方向给出.

一些C++/CLI代码:

g->DrawLine(Pens::Black, 50.0f, 50.0f, 50.0f + oneInchEquivalent / scale, 50.0f);
Run Code Online (Sandbox Code Playgroud)

现在这一点都不难!现在我们需要做的就是计算oneInchEquivalent.

g->DpiX给我一个看起来像屏幕上一英寸但不在打印机上的距离.似乎在打印机上,绘制一行100个单位并g->PageUnit设置为GraphicsUnit :: Display将给我一行一英寸长.但是,无论PageUnit设置如何,我都需要这个工作.事实上,改变PageUnit会改变笔的宽度!

编辑:我暂时接受了这里唯一的答案,因为它非常接近我要找的东西.

Fre*_*örk 12

经过几次编辑后,答案变得相当长,所以这是最终的结果:

将对象的PageUnit属性设置GraphicsGraphicsUnit.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;
}
Run Code Online (Sandbox Code Playgroud)

你可以在Form(或某些控件)上绘制它:

using (Graphics g = this.CreateGraphics())
{
    Point start = new Point(1, 1);
    Point end = new Point(2, 1);
    DrawInchLine(g, Color.Black, start, end);
}
Run Code Online (Sandbox Code Playgroud)

...或将输出发送到打印机:

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();
}
Run Code Online (Sandbox Code Playgroud)

但是,这确实依赖于设置PageUnit.