Results 1 to 3 of 3

Thread: DPI trouble with manual correction of location and size

  1. #1

    Thread Starter
    Member
    Join Date
    Jul 2021
    Posts
    46

    DPI trouble with manual correction of location and size

    I am using Visual Studio 2019 (2022 messes up even more) with Visual Basic .NET framework 3.5 (3.7.2 gives even more headaches).

    Earlier I could screen capture with
    Code:
            
            Dim img As New Bitmap(frm.ClientSize.Width, frm.ClientSize.Height)
            Using gr As Graphics = Graphics.FromImage(img)
                gr.CopyFromScreen(frm.PointToScreen(frm.ClientRectangle.Location), Point.Empty, frm.ClientSize)
            End Using
            img.Save(filename, Imaging.ImageFormat.Png)
    But this does not work on my newer computer with 125% scaling. So I have been trying this which does not work:

    Code:
        Sub SaveFromScreen(frm As Form, fil As String)
    
            Dim g As Graphics = frm.CreateGraphics()
            Dim xDpi As Single = g.DpiX
            Dim scrScale As Single = CSng(xDpi) / 96.0
    
            Dim bmpWidth As Short = frm.ClientSize.Width * scrScale
            Dim bmpHeight As Short = frm.ClientSize.Height * scrScale
    
            Dim img As New Bitmap(bmpWidth, bmpHeight)
    
            Dim scrX1 As Integer = frm.ClientRectangle.Location.X * scrScale
            Dim scrY1 As Integer = frm.ClientRectangle.Location.Y * scrScale
    
            g.CopyFromScreen(scrX1, scrY1, 0, 0, img.Size, CopyPixelOperation.SourceCopy)
            img.Save(fil & ".png", Imaging.ImageFormat.Png)
            img.Save(fil & ".bmp", Imaging.ImageFormat.Bmp)
    
        End Sub
    Please tell me where I am wrong or how to correct this. Thank you very much for any help.

  2. #2
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,371

    Re: DPI trouble with manual correction of location and size

    There are a couple of things off the bat that you should be doing. The first is to wrap your code that implements IDisposable in Using statements. The second is to avoid defining bmpWidth and height as Shorts, instead you should probably be casting these to Integers. Finally, I think you should be using PointToScreen which would automatically take into account the DPI scaling.

    Take a look at this example:
    Code:
    Public Shared Sub SaveFromScreen(frm As Form, fileName As String)
        Using g = frm.CreateGraphics()
            Dim xDpi = g.DpiX
            Dim scrScale = xDpi / 96.0
    
            Dim bmpWidth = Convert.ToInt32(frm.ClientSize.Width * scrScale)
            Dim bmpHeight = Convert.ToInt32(frm.ClientSize.Height * scrScale)
    
            Using img As New Bitmap(bmpWidth, bmpHeight)
                Using gfx = Graphics.FromImage(img)
                    Dim scrX1 = Convert.ToInt32(frm.PointToScreen(frm.ClientRectangle.Location).X)
                    Dim scrX2 = Convert.ToInt32(scrX1 + frm.ClientSize.Width)
    
                    Dim scrY1 = Convert.ToInt32(frm.PointToScreen(frm.ClientRectangle.Location).Y)
                    Dim scrY2 = Convert.ToInt32(scrY1 + frm.ClientSize.Height)
    
                    gfx.CopyFromScreen(scrX1, scrY1, 0, 0, img.Size, CopyPixelOperation.SourceCopy)
                End Using
    
                img.Save($"{fileName}.png", Imaging.ImageFormat.Png)
                img.Save($"{fileName}.bmp", Imaging.ImageFormat.Bmp)
            End Using
        End Using
    End Sub
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  3. #3

    Thread Starter
    Member
    Join Date
    Jul 2021
    Posts
    46

    Re: DPI trouble with manual correction of location and size

    Your corrected code also did not work. It is still not locating the corners correctly.

    Surprisingly, this shows DPI at 96, so scrScale was 1.

    I added a line
    scrScale = 1.25
    to change scrScale to 1.25 to check if the rest was working, but it did not help. It was still wrong. Even the size is wrong. So I tried without scrScale, and still it did not work. I checked with scrScale = 0.8 and still it does not work. Any idea where the trouble is?

    Thanks for your help.

    Quote Originally Posted by dday9 View Post
    There are a couple of things off the bat that you should be doing. The first is to wrap your code that implements IDisposable in Using statements. The second is to avoid defining bmpWidth and height as Shorts, instead you should probably be casting these to Integers. Finally, I think you should be using PointToScreen which would automatically take into account the DPI scaling.

    Take a look at this example:
    Code:
    Public Shared Sub SaveFromScreen(frm As Form, fileName As String)
        Using g = frm.CreateGraphics()
            Dim xDpi = g.DpiX
            Dim scrScale = xDpi / 96.0
    
            Dim bmpWidth = Convert.ToInt32(frm.ClientSize.Width * scrScale)
            Dim bmpHeight = Convert.ToInt32(frm.ClientSize.Height * scrScale)
    
            Using img As New Bitmap(bmpWidth, bmpHeight)
                Using gfx = Graphics.FromImage(img)
                    Dim scrX1 = Convert.ToInt32(frm.PointToScreen(frm.ClientRectangle.Location).X)
                    Dim scrX2 = Convert.ToInt32(scrX1 + frm.ClientSize.Width)
    
                    Dim scrY1 = Convert.ToInt32(frm.PointToScreen(frm.ClientRectangle.Location).Y)
                    Dim scrY2 = Convert.ToInt32(scrY1 + frm.ClientSize.Height)
    
                    gfx.CopyFromScreen(scrX1, scrY1, 0, 0, img.Size, CopyPixelOperation.SourceCopy)
                End Using
    
                img.Save($"{fileName}.png", Imaging.ImageFormat.Png)
                img.Save($"{fileName}.bmp", Imaging.ImageFormat.Bmp)
            End Using
        End Using
    End Sub

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width