【问题标题】:Different scaling when drawing Metafile on different machines在不同机器上绘制图元文件时不同的缩放比例
【发布时间】:2015-01-06 05:17:34
【问题描述】:

我在使用以毫米为度量单位的元文件的 WinForms 应用程序中获得一致的缩放比例时遇到问题。我写了一个小示例应用程序来说明这个问题。

这是应用程序在 Windows 7 桌面计算机上的外观:

这是应用程序在 Windows 8 笔记本电脑上的外观:

源代码:

private void MainForm_Paint(object sender, PaintEventArgs e)
{
   var g = e.Graphics;
   var blueBrush = new SolidBrush(Color.Blue);
   var bluePen = new Pen(blueBrush);
   g.DrawRectangle(bluePen, 0, 0, 200, 200);
   g.DrawLine(bluePen, 100, 0, 100, 200);
   g.DrawLine(bluePen, 0, 100, 200, 100);
   g.DrawString(g.DpiX+" dpi", new Font("Arial", 10), blueBrush, 0, 205);

   Metafile metafile;
   var size = new Size(200, 200);
   using (var stream = new MemoryStream())
   {
      using (Graphics offScreenBufferGraphics = Graphics.FromHwndInternal(IntPtr.Zero))
      {
         IntPtr deviceContextHandle = offScreenBufferGraphics.GetHdc();
         metafile = new Metafile(stream, deviceContextHandle, new RectangleF(0, 0, size.Width, size.Height), MetafileFrameUnit.Millimeter, EmfType.EmfPlusOnly);
         offScreenBufferGraphics.ReleaseHdc();

         using (Graphics mg = Graphics.FromImage(metafile))
         {
            mg.PageUnit = GraphicsUnit.Millimeter;

            var redPen = new Pen(new SolidBrush(Color.Red));
            const float scaleFactor = 0.75f;
            mg.ScaleTransform(scaleFactor, scaleFactor);
            mg.DrawLine(redPen, 0, 0, 200, 200);
            mg.DrawLine(redPen, 0, 200, 200, 0);
         }
      }
   }

   g.DrawImage(metafile, 0, 0, 200, 200);
}

两台机器都设置为 96dpi,但 Win8 机器将元文件(红十字)渲染得更小。

比例因子 0.75 是根据标准 72 dpi 和当前 96 dpi 的差值计算得出的,72/96=0.75,这样是否正确? 编辑:请参阅下面的答案为什么这不起作用。

但大多数情况下,为什么它在 Win8 机器上的缩放比例不同,我可以获取什么设置来补偿?好像Win8机器需要1.25左右的比例因子才能使红十字与蓝色矩形对齐。

谢谢!

【问题讨论】:

    标签: winforms metafile


    【解决方案1】:

    在阅读this代码项目文章后自己找到了答案。事实证明,机器上的屏幕尺寸(台式机上的 1920x1200 和笔记本电脑上的 1600x900)会影响图元文件的分辨率。用于计算比例因子 0.75 的 72dpi 假设在我的台式机上有些正确,但在 Win8 笔记本电脑上则不然。

    可以从图元文件头中获取图元文件的分辨率,然后用来计算正确的缩放因子:

    var metafileHeader = metafile.GetMetafileHeader();
    float sx = metafileHeader.DpiX/g.DpiX;
    float sy = metafileHeader.DpiY/g.DpiY;
    mg.ScaleTransform(sx, sy);
    

    完整代码见here

    然后我在两台机器上都得到了正确的缩放:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-05
      • 1970-01-01
      • 2020-05-18
      • 2019-04-17
      • 1970-01-01
      • 2018-01-31
      相关资源
      最近更新 更多