代码之家  ›  专栏  ›  技术社区  ›  Agnel Kurian

gdi+:我如何在任何设备上画一条1英寸长的线?

  •  12
  • Agnel Kurian  · 技术社区  · 16 年前

    我需要在任何设备上画一条一英寸长的线 Graphics 参考它。不管怎样,我需要一英寸长 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将为我提供一英寸长的行。但是,我真的需要这个来工作,不管 PageUnit 设置。事实上,改变 分页单元 将更改笔的宽度!!

    编辑: 我暂时接受了这里唯一的答案,因为它非常接近我正在寻找的。

    1 回复  |  直到 16 年前
        1
  •  12
  •   Fredrik Mörk    16 年前

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

    设置 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();
    }
    

    但是,这取决于设置 分页单元 .