|
-
Aug 23rd, 2024, 11:31 AM
#1
Thread Starter
Member
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.
-
Aug 23rd, 2024, 01:16 PM
#2
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
-
Aug 24th, 2024, 03:31 AM
#3
Thread Starter
Member
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.
 Originally Posted by dday9
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|