Resolved output of .Location.X/.Y is not accurate?

love_lyn99

Member
Joined
Sep 2, 2022
Messages
16
Programming Experience
Beginner
Hi, im having difficulty in getting the accurate location of the image i want to capture, how do i correct this? ive tried to manually put the X and Y number but the result was the same. (Please see Attached Image, The First Image is the whole form and the second image was the result after pressing "Capture" button). am i missing something?. i have attached the code i use for you to see.


VB:
Public Class Form1

    Dim memoryImage As Bitmap

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        PictureBox1.SendToBack()
    End Sub

    Private Sub CaptureScreen()
        Dim s As Size = RectangleShape1.Size
        memoryImage = New Bitmap(s.Width, s.Height)
        Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
        memoryGraphics.CopyFromScreen(RectangleShape1.Location.X, RectangleShape1.Location.Y, 0, 0, s)
        memoryImage.Save("D:\Library\Pictures\Screenshot.png")
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        CaptureScreen()
    End Sub
End Class

-----------------------

Capture.JPG

Screenshot.png
 
Given that CopyFromScreen can copy anywhere from the screen, it stands to reason that the source coordinates are relative to the screen. Is RectangleShape1.Location relative to the screen? No it is not, so it's not going to work as you desire. You need to translate that Point to screen coordinates first, then use that result as the source for CopyFromScreen.

You will need to use the PointToScreen method of the appropriate control to do that, but I'm not sure exactly what that control is. I'm guessing that you're using the VB PowerPacks to get that RectangleShape. If I remember correctly, the shapes themsleves are not controls but they live in a ShapeContainer or the like that is. In that case, you'd do something like this:
VB.NET:
Dim sourceLocation = ShapeContainer1.PointToScreen(RectangleShape1.Location)
If the Location of a shape is actually relative to the form, rather than the ShapeContainer, then you can just use the form's PointToScreen method. Thinking about it, it may be that the ShapeContainer actually fills the whole form anyway, so they might produce the same result.
 
Given that CopyFromScreen can copy anywhere from the screen, it stands to reason that the source coordinates are relative to the screen. Is RectangleShape1.Location relative to the screen? No it is not, so it's not going to work as you desire. You need to translate that Point to screen coordinates first, then use that result as the source for CopyFromScreen.

You will need to use the PointToScreen method of the appropriate control to do that, but I'm not sure exactly what that control is. I'm guessing that you're using the VB PowerPacks to get that RectangleShape. If I remember correctly, the shapes themsleves are not controls but they live in a ShapeContainer or the like that is. In that case, you'd do something like this:
VB.NET:
Dim sourceLocation = ShapeContainer1.PointToScreen(RectangleShape1.Location)
If the Location of a shape is actually relative to the form, rather than the ShapeContainer, then you can just use the form's PointToScreen method. Thinking about it, it may be that the ShapeContainer actually fills the whole form anyway, so they might produce the same result.
yay! it works!. the RectangleShape1 is from VB PowerPacks and it lives in ShapeContainer1.

upon trying to understand your explanation and me playing with codes. we finally solve it.. and i was able to display the captured image in PictureBox2 also. thank you.
here's the code:

ScreenCapture:
Private Sub CaptureScreen()

        Dim s As Size = RectangleShape1.Size
        memoryImage = New Bitmap(s.Width, s.Height) 'Get Output Size'
        Dim sl = ShapeContainer1.PointToScreen(RectangleShape1.Location) 'Get Target Location'
        Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
        memoryGraphics.CopyFromScreen((sl), Point.Empty, s)
        PictureBox2.Image = memoryImage 'Display Captured Image in PictureBox2'

        'memoryGraphics.CopyFromScreen(New Point(RectangleShape1.Location.X, RectangleShape1.Location.Y), New Point(0, 0), New Size(s)) 'Get Target Location - old'
        'memoryImage.Save("D:\Library\Pictures\Screenshot.png") 'Save File'
    End Sub

maybe someone will need it in the future.
 
Last edited:
Don't do this:
VB.NET:
ShapeContainer1.PointToScreen(New Point(RectangleShape1.Location.X, RectangleShape1.Location.Y))
That Location property already is type Point, so just use that as I already demonstrated.
 
Don't do this:
VB.NET:
ShapeContainer1.PointToScreen(New Point(RectangleShape1.Location.X, RectangleShape1.Location.Y))
That Location property already is type Point, so just use that as I already demonstrated.
oh. so basically i made it redundant. my bad. Thank you!
 
Back
Top