Clint Carter
Clint Carter

Reputation: 19

Graphics.DrawImage on High DPI 150%+ Only Draws Portion of the Image

This issue happens on Windows 10 Creators Update or later using 175% zoom or higher targeted .Net 4.7.2. Further, we are calling SetProcessDPIAware in the Program.cs file.

If we do not call this then fonts look horrible on High DPI, especially at 300%.

static class Program
{
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool SetProcessDPIAware();

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        //if (Environment.OSVersion.Version.Major >= 6)
        SetProcessDPIAware();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

IMPORTANT STEP We also go into Advanced Scaling Settings and turn off the feature "Let windows try to fix apps so they are not blurry"...because we have users turning this off. Image of the Windows Setting

In the application below, we have 3 PictureBox controls. The PictureBox on the far left is the source and his image is a PNG file created at 96 dpi.

The user clicks the button above the middle PictureBox to copy the source image into a Metafile (used as the drawing canvas) and uses that to populate the Image property of the middle PictureBox. In High DPI you can see that the image does not size well or that only a portion of the image was copied into the metafile.

The button above the PictureBox on the far right copies the source Image using a Bitmap as the drawing canvas. He renders properly at 175%.

Picture of Application Results

This is the code that converts the source image to a metafile and sticks it into another PictureBox.

      private void DrawUsingMetafile()
    {
        try
        {
            Image img = this.pictureBox1.Image;

            Metafile mf = NewMetafile();

            using (Graphics gmf = Graphics.FromImage(mf))
            {
                gmf.DrawImage(img, 0, 0, img.Width, img.Height);
            }

            this.pictureBox2.Image = mf;
        }
        catch (Exception ex)
        {

            MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

}

        public static Metafile NewMetafile()
    {
        using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))  // offscreen device context
        {
            IntPtr hdc = g.GetHdc(); // gets released by g.Dispose() called by using g
            return new Metafile(hdc, EmfType.EmfPlusOnly);
        }
    }

Any ideas why this is happening?

Upvotes: 1

Views: 625

Answers (1)

Clint Carter
Clint Carter

Reputation: 19

Just FYI - Microsoft confirmed this was a bug in .Net 4.8. The problem happens only if you turn off the feature "Let windows try to fix apps so they are not blurry" They confirmed the issue and patched it but have not released that fix as of yet.

Upvotes: 0

Related Questions