-
1 Attachment(s)
Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Here is a class that contains very easy methods to get screen captures. It is not code originally written by me, it was actually found Here. It was originally written in C#, and there was supposedly a VB.NET example in there, however it just looked as if it was ran through some code converter that didn't work. I cleaned it up in order for it to work in .NET, replaced all the API declarations with the correct working ones, and even added a CaptureDeskTopRectangle function to it for desktop regions.
The file has its own namespace, "ScreenShot", which includes three seperate classes:
ScreenCapture - Main class, contains functions for obtaining the actual images
GDI32 = Helper Class with various GDI Functions that are used
USER32 - Helper Class with various User32 Functions used
The ScreenCapture has five exposed functions and methods that enables you to get captures:
CaptureWindow - grabs image of object by its handle
CaptureScreen - grabs image of entire screen
CaptureWindowToFile - captures image of object by its handle straight to file
CaptureScreenToFile - captures image of screen straight to file
CaptureDesktopRectangle - captures desktop region by a passed in rectangle
***.NET 2005 has a .CopyFromScreen method in the Graphics class that allows you to get a desktop region, however, there is no way in 2003, which is why CaptureDesktopRectangle was needed...
Sample code showing how to use each method is below, the class is available for download at the end of the post.
VB Code:
Dim SC As New ScreenShot.ScreenCapture
'grabs image of object handle (in this case, the form)
Dim MyWindow As Image = SC.CaptureWindow(Me.Handle)
'grabs image of entire desktop
Dim MyDesktop As Image = SC.CaptureScreen
'captures entire desktop straight to file
SC.CaptureScreenToFile("c:\desktop2.jpg", Imaging.ImageFormat.Jpeg)
'captures image of object handle (in this case, the form) straight to file
SC.CaptureWindowToFile(Me.Handle, "c:\window2.jpg", Imaging.ImageFormat.Jpeg)
'returns bitmap of region of desktop by passing in a rectangle
Dim MyBitMap As Bitmap = SC.CaptureDeskTopRectangle(New Rectangle(Me.Location.X, Me.Location.Y, _
Me.Width, Me.Height), Me.Width, Me.Height)
MyBitMap.Save("c:\desktopregion.jpg", Imaging.ImageFormat.Jpeg)
'above example gets rectangle of form that it is called in, you can get
'desktop by calling me.hide before the actual function call in order to
'get the desktop that is in the bounds of the form (handy when using a
'transparent Form or control in order to make a "viewfinder" for the capture...)
'You can pass in any rectangle you want, this was so you can see how
'it works...
Happy coding! :)
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
this is very useful
thank you
rgds
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Very neat, anyone make a windows app or a console app for this yet using this?
I'd love to check it out.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
EZScreenCap in my sig was made using it, nothing fancy and I didn't spend a lot of time doing it. Just sort of a proof of concept...
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
gigemboy,
Thanks for the code it is exacually what I have been looking for, however I am having a really hard time trying to create the code to allow the user to specify a region using mouse clicks. I noticed in your EZScreenCap you have this ability and I was wondering if you would be able to help with the code that you used to acheive this.
Thanks inadvance
Simon
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Using mouse clicks?? You mean the "Viewfinder"? Its just a transparent panel on a form, and it gets the bounds of panel when you capture it (after first hiding the form so it doesnt capture the form). The last code above describes it, although in the example it uses the form bounds.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
when i click on the attatchment, a html web page comes up and all the code is like a textfile, is it meant to be like this, or is it an error.
Ideally id like to see how the application works, so I can use it for somthing.
MB
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Are you talking about the Class attachment? Its just a file.. if it doesn't ask you to save then your browser is set to do something automatically with that file. Just right click the link and choose "save target as" or something. If you just see the text, just save that file as a .VB file and add it to your project...
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Hi i have been using your class but i have little problem. I have this loop that takes a sceenshot, and then analyzes it. every time i use the class to take a screenshot, it filles my RAM with 6 extra megabytes (and it takes approx. 1 screenshot every second. So after aboute 1 minute, it uses approx 700 MB RAM :S:S.. why?
VB Code:
Dim SIR As New SteffansImageRecognizion()
Dim SC As New ScreenShot.ScreenCapture
Dim ColorBuffer As System.Drawing.Color
Dim BitmapBuffer As System.Drawing.Bitmap
Dim ImageBuffer As System.Drawing.Image
While (True)
BitmapBuffer = SC.CaptureDeskTopRectangle(New System.Drawing.Rectangle(0, 0, 0, 0), 1000, 700)
' Lots of code..
End While
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Then I assume its something in your code that is not being disposed of properly, whatever you are doing in it. I don't believe its a problem in the class. I tested EZScreenCap, which uses the class, and after taking a few snapshots, the memory increased by about 10-20 megabytes after taking a few quick snapshots in rapid succession, but after a short time, it goes back down to about where it was before (a little higher just because of the extra graphics that it has to display in the listview), after the garbage collector does its job and cleans up...
If you want to get help with your code, then feel free to post it, but please create a new thread in the regular VB.NET section for it if you desire.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Hi, I need to know how I can use your code on pocket pc using compact framework?!
Thanks a lot.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
gigemboy,
Do you know of a way to capture an image on a remote machine? Assuming that you have the correct permissions to do so.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
this screen capture is great but i was wondering is it possible to take screen shots of the window when the window is minimised?
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
I get three errors by using the example.
Declaration expected.
Imports System.Windows.Forms
Public Class Form1
Dim SC As New ScreenShot.ScreenCapture
'grabs image of object handle (in this case, the form)
Dim MyWindow As Image = SC.CaptureWindow(Me.handle)
'grabs image of entire desktop
Dim MyDesktop As Image = SC.CaptureScreen
'captures entire desktop straight to file
SC.CaptureScreenToFile("c:\desktop2.jpg", Imaging.ImageFormat.Jpeg) 'Here SC
'captures image of object handle (in this case, the form) straight to file
SC.CaptureWindowToFile(Me.Handle, "c:\window2.jpg", Imaging.ImageFormat.Jpeg) 'Here SC
'returns bitmap of region of desktop by passing in a rectangle
Dim MyBitMap As Bitmap = SC.CaptureDeskTopRectangle(New Rectangle(Me.Location.X, Me.Location.Y, _
Me.Width, Me.Height), Me.Width, Me.Height)
MyBitMap.Save("c:\desktopregion.jpg", Imaging.ImageFormat.Jpeg) 'Here MyBitMap
'above example gets rectangle of form that it is called in, you can get
'desktop by calling me.hide before the actual function call in order to
'get the desktop that is in the bounds of the form (handy when using a
'transparent Form or control in order to make a "viewfinder" for the capture...)
'You can pass in any rectangle you want, this was so you can see how
'it works...
End Class
Anybody can help?
Thanks
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
I am currently having trouble with trying to implement the code.
Code:
Imports System
Imports System.Diagnostics
Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports DirectShowLib
Imports System.Runtime.InteropServices.ComTypes
Imports System.ComponentModel
Namespace Capture_The_Webcam
Public Class Form1
Inherits System.Windows.Forms.Form
'webcam code from http://www.codeproject.com/KB/audio-video/WebcamUsingDirectShowNET.aspx
'webcam feed is handled by picturebox1
Public Class ScreenCapture
Dim SC As New ScreenShot.ScreenCapture
'grabs image of object handle (in this case, the form)
Dim MyWindow As Image = SC.CaptureWindow(Capture2.Capture_The_Webcam.Form1.PictureBox1.Handle)
'Dim SC As ScreenCapture.Screenshot
Public SRCCOPY As Integer = &HCC0020
' BitBlt dwRop parameter
Declare Function BitBlt Lib "gdi32.dll" ( _
ByVal hDestDC As IntPtr, _
ByVal x As Int32, _
ByVal y As Int32, _
ByVal nWidth As Int32, _
ByVal nHeight As Int32, _
ByVal hSrcDC As IntPtr, _
ByVal xSrc As Int32, _
ByVal ySrc As Int32, _
ByVal dwRop As Int32) As Int32
Declare Function CreateCompatibleBitmap Lib "gdi32.dll" ( _
ByVal hdc As IntPtr, _
ByVal nWidth As Int32, _
ByVal nHeight As Int32) As IntPtr
Declare Function CreateCompatibleDC Lib "gdi32.dll" ( _
ByVal hdc As IntPtr) As IntPtr
Declare Function DeleteDC Lib "gdi32.dll" ( _
ByVal hdc As IntPtr) As Int32
Declare Function DeleteObject Lib "gdi32.dll" ( _
ByVal hObject As IntPtr) As Int32
Declare Function SelectObject Lib "gdi32.dll" ( _
ByVal hdc As IntPtr, _
ByVal hObject As IntPtr) As IntPtr
End Class 'GDI32
'/ Helper class containing User32 API functions
Public Class User32
<StructLayout(LayoutKind.Sequential)> _
Public Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
End Structure 'RECT
'/ Helper class containing Gdi32 API functions
Public Class GDI32
Public SRCCOPY As Integer = &HCC0020
' BitBlt dwRop parameter
Declare Function BitBlt Lib "gdi32.dll" ( _
ByVal hDestDC As IntPtr, _
ByVal x As Int32, _
ByVal y As Int32, _
ByVal nWidth As Int32, _
ByVal nHeight As Int32, _
ByVal hSrcDC As IntPtr, _
ByVal xSrc As Int32, _
ByVal ySrc As Int32, _
ByVal dwRop As Int32) As Int32
Declare Function CreateCompatibleBitmap Lib "gdi32.dll" ( _
ByVal hdc As IntPtr, _
ByVal nWidth As Int32, _
ByVal nHeight As Int32) As IntPtr
Declare Function CreateCompatibleDC Lib "gdi32.dll" ( _
ByVal hdc As IntPtr) As IntPtr
Declare Function DeleteDC Lib "gdi32.dll" ( _
ByVal hdc As IntPtr) As Int32
Declare Function DeleteObject Lib "gdi32.dll" ( _
ByVal hObject As IntPtr) As Int32
Declare Function SelectObject Lib "gdi32.dll" ( _
ByVal hdc As IntPtr, _
ByVal hObject As IntPtr) As IntPtr
End Class 'GDI32
'/ Creates an Image object containing a screen shot of a specific window
Public Function CaptureWindow(ByVal handle As IntPtr) As Image
Dim SRCCOPY As Integer = &HCC0020
' get te hDC of the target window
Dim hdcSrc As IntPtr = User32.GetWindowDC(handle)
' get the size
Dim windowRect As New User32.RECT
User32.GetWindowRect(handle, windowRect)
Dim width As Integer = 640
Dim height As Integer = 480
' create a device context we can copy to
Dim hdcDest As IntPtr = GDI32.CreateCompatibleDC(hdcSrc)
' create a bitmap we can copy it to,
' using GetDeviceCaps to get the width/height
Dim hBitmap As IntPtr = GDI32.CreateCompatibleBitmap(hdcSrc, width, height)
' select the bitmap object
Dim hOld As IntPtr = GDI32.SelectObject(hdcDest, hBitmap)
' bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY)
' restore selection
GDI32.SelectObject(hdcDest, hOld)
' clean up
GDI32.DeleteDC(hdcDest)
User32.ReleaseDC(handle, hdcSrc)
' get a .NET image object for it
Dim img As Image = Image.FromHbitmap(hBitmap)
' free up the Bitmap object
GDI32.DeleteObject(hBitmap)
Return img
End Function 'CaptureWindow
Function Function1()
''captures image of object handle (in this case, the form) straight to file
SC.CaptureWindowToFile(Capture2.Capture_The_Webcam.Form1.PictureBox1.Handle, "c:\ProgramFiles\ImgCap\Tmp.bmp", Imaging.ImageFormat.BMP)
Return 0
End Function
Declare Function GetDesktopWindow Lib "user32.dll" () As IntPtr
Declare Function GetWindowDC Lib "user32.dll" ( _
ByVal hwnd As IntPtr) As IntPtr
Declare Function ReleaseDC Lib "user32.dll" ( _
ByVal hwnd As IntPtr, _
ByVal hdc As IntPtr) As Int32
Declare Function GetWindowRect Lib "user32.dll" ( _
ByVal hwnd As IntPtr, _
ByRef lpRect As RECT) As Int32
End Class
Private Sub ButtonX_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonX.Click
Dim SecondsNow As Integer = Second(Now)
While Second(Now) < 1 + SecondsNow
ButtonX.Enabled = False
End While
Dim test As New User32
test.Function1()
End Sub
End Class
End Namespace
I keep getting the error that Screenshot.Screencapture is not defined. Any ideas?
THanks
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Hi,
After some fiddling around, the problem was fixed by putting all the screen capture class code BEFORE the Capture_the_Webcam code.
Much better now, great code it was very helpful. Thank you :wave:
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Hi guys, this code works but what i'm trying to do is get this code to take the picture and set it in a different directory .. anyone got an answer?
Code:
Dim SC As New ScreenShot.ScreenCapture
Dim windowList As List(Of Game.WindowInfo) = Game.GetWindowList()
Dim screenshotname As String
screenshotname = grpInfo.Text & ".jpg"
SC.CaptureWindowToFile(DirectCast(windowList(lstGame.SelectedIndex), Game.WindowInfo).Handle, screenshotname, Imaging.ImageFormat.Jpeg)
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Quote:
Originally Posted by
mcManiac
Hi guys, this code works but what i'm trying to do is get this code to take the picture and set it in a different directory .. anyone got an answer?
Code:
Dim SC As New ScreenShot.ScreenCapture
Dim windowList As List(Of Game.WindowInfo) = Game.GetWindowList()
Dim screenshotname As String
screenshotname = grpInfo.Text & ".jpg"
SC.CaptureWindowToFile(DirectCast(windowList(lstGame.SelectedIndex), Game.WindowInfo).Handle, screenshotname, Imaging.ImageFormat.Jpeg)
where you have screenshotname, what about if you add the path you want to save the image to and then specify grpInfo.Text & ".jpg"
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Hi,
very good code, but i have a problem with my second monitor. On this screen the created screenshots are black.
Can anybody help?
Thanks a lot.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
To the original poster: THANKS! This is cool stuff you've passed along and it saved me some time for sure.
To the last poster: I had a similar problem. I have lots of monitors and was getting nowhere trying to get a screenshot of all of them at the same time.
GetDesktopWindow() API call will return the handle only for the primary video display, not the entire screen output.... booooo MS!!...... so this code will only take a screenshot of ONE monitor as is.
For the original poster: Instead of using User32.GetDesktopWindow() I found the REAL Window that represents the desktop and modified your code so it will work across ALL screens.
Code:
Dim base As IntPtr = User32.FindWindow("Progman", "Program Manager")
Dim b2 As IntPtr = User32.FindWindowEx(base, vbNullString, "SHELLDLL_DefView", vbNullString)
b2 = User32.FindWindowEx(b2, vbNullString, "SysListView32", vbNullString)
Return CaptureWindow(b2)
Before, the function was just Return CaptureWindow(User32.GetDesktopWindow())
also added:
<Runtime.InteropServices.DllImport("User32.dll")> _
Public Shared Function FindWindowEx(ByVal hwndParent As IntPtr, ByVal hwndChild As IntPtr, ByVal className As String, ByVal caption As String) As IntPtr
End Function
<Runtime.InteropServices.DllImport("User32.dll")> _
Public Shared Function FindWindow(ByVal className As String, ByVal caption As String) As IntPtr
End Function
I'm pretty sure this behavior is consistent across all versions of Windows but I've only tested this in XP.
Anyways, hope this saves someone else a headache, thanks again.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Can somebody update the code to work with Microsoft Visual Basic 2008 for me? (And Post it for me too please!)
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
I really want this class in C#. I've found one online but the "DesktopRectangle()" method isn't there.
Is it possible to get this class in C#?
Thanks
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Very easy to use class, thanks alot! I spent hours trying to capture this control with no luck, until I added this class. Here is an app I made that uses it to capture the control that is drawn on.
Lite Brite
-
1 Attachment(s)
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Quote:
Originally Posted by
NonProgrammer
Can somebody update the code to work with Microsoft Visual Basic 2008 for me? (And Post it for me too please!)
I just stumbled on this code and it seems perfect, if I could only get it to work. I'm running VS 2008 as well and I'm running into several problems.
- Me.Handle is not recognized
- Me.Location.X is not recognized
- etc
- Also I'm getting an error when I try to save the image to a file
I've attached my code behind
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Hi
im new to VB.NET... Can u pls tel me how to implement the code?? i mean form ? coz i have created a new form and pasted the cod ein designer.. but its showing some error and the form was not loading:-(
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Hey ramesh, do you know what a class is? This is not code you can paste into a form, you have to make calls to the class from your form code.
Classes
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Cool... I need a piece of code which will capture screen shot of the form.. Can u help me to get it form this code!!
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
First you must add the SCapture.vb class file to your project in the solution explorer. Then you have to make a button on your form so you can have an event to capture the form picture. In the button's click event handler add this code:
Code:
Dim filePath As String = My.Computer.FileSystem.SpecialDirectories.Desktop & "\myFormImage.png"
Try
Dim img As Image = SCapture.Control(Me.Handle, False)
img.Save(filePath, Drawing.Imaging.ImageFormat.Png)
Catch ex As Exception
MessageBox.Show("Failed to capture the control!" _
& Environment.NewLine & ex.Message, "Capture Error!", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Then when you click the button you put this code in, it should save a png image of your form to your desktop.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
I did the same what u told.. But its showing soem error:-(
Also it is saying that Name 'screencapture' is not declared
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Code:
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim filePath As String = "C:\Documents and Settings\175943\Desktop\mypicture.png"
Try
Dim img As Image = screencapture.Control(Me.Handle, False)
img.Save(filePath, Drawing.Imaging.ImageFormat.Png)
Catch ex As Exception
MessageBox.Show("Failed to capture the control!" _
& Environment.NewLine & ex.Message, "Capture Error!", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub Capture_window_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Capture_window.CheckedChanged
If Capture_window.Checked Then
Me.Opacity = 0.6
Else
Me.Opacity = 1
End If
If Capture_window.Checked And Doc_Button.Checked Then
Button2.Visible = False
Button1.Visible = False
Button3.Visible = True
ElseIf Capture_window.Checked And Img_Button.Checked Then
Button2.Visible = False
Button1.Visible = False
Button3.Visible = True
ElseIf Doc_Button.Checked = True Then
Button3.Visible = False
Button2.Visible = True
Button3.ForeColor = Color.Blue
End If
End Sub
Public Class screencapture
Public Function CaptureScreen() As Image
Return CaptureWindow(User32.GetDesktopWindow())
End Function 'CaptureScreen
'/ Creates an Image object containing a screen shot of a specific window
Public Function CaptureWindow(ByVal handle As IntPtr) As Image
Dim SRCCOPY As Integer = &HCC0020
' get te hDC of the target window
Dim hdcSrc As IntPtr = User32.GetWindowDC(handle)
' get the size
Dim windowRect As New User32.RECT
User32.GetWindowRect(handle, windowRect)
Dim width As Integer = windowRect.right - windowRect.left
Dim height As Integer = windowRect.bottom - windowRect.top
' create a device context we can copy to
Dim hdcDest As IntPtr = GDI32.CreateCompatibleDC(hdcSrc)
' create a bitmap we can copy it to,
' using GetDeviceCaps to get the width/height
Dim hBitmap As IntPtr = GDI32.CreateCompatibleBitmap(hdcSrc, width, height)
' select the bitmap object
Dim hOld As IntPtr = GDI32.SelectObject(hdcDest, hBitmap)
' bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY)
' restore selection
GDI32.SelectObject(hdcDest, hOld)
' clean up
GDI32.DeleteDC(hdcDest)
User32.ReleaseDC(handle, hdcSrc)
' get a .NET image object for it
Dim img As Image = Image.FromHbitmap(hBitmap)
' free up the Bitmap object
GDI32.DeleteObject(hBitmap)
Return img
End Function 'CaptureWindow
'/ Captures a screen shot of a specific window, and saves it to a file
Public Sub CaptureWindowToFile(ByVal handle As IntPtr, ByVal filename As String, ByVal format As ImageFormat)
Dim img As Image = CaptureWindow(handle)
img.Save(filename, format)
End Sub 'CaptureWindowToFile
'/ Captures a screen shot of the entire desktop, and saves it to a file
Public Sub CaptureScreenToFile(ByVal filename As String, ByVal format As ImageFormat)
Dim img As Image = CaptureScreen()
img.Save(filename, format)
End Sub 'CaptureScreenToFile
Public Function CaptureDeskTopRectangle(ByVal CapRect As Rectangle, ByVal CapRectWidth As Integer, ByVal CapRectHeight As Integer) As Bitmap
'/ Returns BitMap of the region of the desktop, similar to CaptureWindow, but can be used to
'/ create a snapshot of the desktop when no handle is present, by passing in a rectangle
'/ Grabs snapshot of entire desktop, then crops it using the passed in rectangle's coordinates
Dim SC As New MainWindow.screencapture
Dim bmpImage As New Bitmap(SC.CaptureScreen)
Dim bmpCrop As New Bitmap(CapRectWidth, CapRectHeight, bmpImage.PixelFormat)
Dim recCrop As New Rectangle(CapRect.X, CapRect.Y, CapRectWidth, CapRectHeight)
Dim gphCrop As Graphics = Graphics.FromImage(bmpCrop)
Dim recDest As New Rectangle(0, 0, CapRectWidth, CapRectHeight)
gphCrop.DrawImage(bmpImage, recDest, recCrop.X, recCrop.Y, recCrop.Width, _
recCrop.Height, GraphicsUnit.Pixel)
Return bmpCrop
End Function
'/ Helper class containing Gdi32 API functions
Private Class GDI32
Public SRCCOPY As Integer = &HCC0020
' BitBlt dwRop parameter
Declare Function BitBlt Lib "gdi32.dll" ( _
ByVal hDestDC As IntPtr, _
ByVal x As Int32, _
ByVal y As Int32, _
ByVal nWidth As Int32, _
ByVal nHeight As Int32, _
ByVal hSrcDC As IntPtr, _
ByVal xSrc As Int32, _
ByVal ySrc As Int32, _
ByVal dwRop As Int32) As Int32
Declare Function CreateCompatibleBitmap Lib "gdi32.dll" ( _
ByVal hdc As IntPtr, _
ByVal nWidth As Int32, _
ByVal nHeight As Int32) As IntPtr
Declare Function CreateCompatibleDC Lib "gdi32.dll" ( _
ByVal hdc As IntPtr) As IntPtr
Declare Function DeleteDC Lib "gdi32.dll" ( _
ByVal hdc As IntPtr) As Int32
Declare Function DeleteObject Lib "gdi32.dll" ( _
ByVal hObject As IntPtr) As Int32
Declare Function SelectObject Lib "gdi32.dll" ( _
ByVal hdc As IntPtr, _
ByVal hObject As IntPtr) As IntPtr
End Class 'GDI32
'/ Helper class containing User32 API functions
Public Class User32
<StructLayout(LayoutKind.Sequential)> _
Public Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
End Structure 'RECT
Declare Function GetDesktopWindow Lib "user32.dll" () As IntPtr
Declare Function GetWindowDC Lib "user32.dll" ( _
ByVal hwnd As IntPtr) As IntPtr
Declare Function ReleaseDC Lib "user32.dll" ( _
ByVal hwnd As IntPtr, _
ByVal hdc As IntPtr) As Int32
Declare Function GetWindowRect Lib "user32.dll" ( _
ByVal hwnd As IntPtr, _
ByRef lpRect As RECT) As Int32
End Class 'User32
End Class 'ScreenCapture
Refer the code above..
I got an error that control is not a member of 'mainwindow .screencapture'.
-
1 Attachment(s)
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
You must add the class file to your solution explorer. You can't add the class code to your form. You can either right click your project in solution explorer or you can use the add item menu item. You pick add existing item and navigate to where your class file is stored then select it to add it to your project. Then remove the class code from your form code. See attached picture for an example.
-
1 Attachment(s)
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Hey Brian,
Thanks for your effort to teach me!! I have doen the same thing.. But its showing lot of errors!!
PFAAttachment 76557Attachment 76557
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
What version of Visual Studios are you using? This class is written for 2005.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Hi all
Can anybody help me??...
Dear all
I have an application which provides some data in datagrid ... by right click i can copy that and past that in to a text file.....
my quest is can i get this process done by vb.net code
Please help me
thanks in advance
sansharam
:)
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Using this screencapture class win winxp, and it does what i want. :thumb: very easy to use.
However on Windows 7 pc's (32 or 64 bit) - i get black image...:(
Any solutions for this win7 issue?
Just to add: the app i am making is SERVICE BASED & currently it works on WinXP, when installed on Win7, just black image.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Excellent class! So useful! Hard to believe .NET doesnt have this built in. Great solution though!
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Quote:
Originally Posted by
Dario
Using this screencapture class win winxp, and it does what i want. :thumb: very easy to use.
However on Windows 7 pc's (32 or 64 bit) - i get black image...:(
Any solutions for this win7 issue?
Just to add: the app i am making is SERVICE BASED & currently it works on WinXP, when installed on Win7, just black image.
Grrr been googling for 2 weeks on this issue, and all i can find is that some people have the same problem, and that windows 7 gdi/win32 api has changed a great deal since introduction of VISTA and onwards, windows 7.
http://stackoverflow.com/questions/1...indows-service
Going crazy..:cry::eek2:
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
I am having a weird problem and was hoping someone could offer a pointer or two...
Consider the following sub:
Code:
Private Sub _timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs)
Dim sc As New ScreenShot.ScreenCapture
Debug.Print("Tick: " & Now)
If rdp.Count > 0 Then
For Each r As _rdp In rdp
r.pic.Image = sc.CaptureWindow(r.rdp.Handle).GetThumbnailImage(160, 120, Nothing, Nothing)
Next
End If
sc = Nothing
End Sub
It triggers every 3 seconds, refreshing the r.pic.image with a screen cap from r.rdp.handle. Pretty straight forward, right? Well, except what is happening is that the resulting image is re-shrunk every iteration so the first image is 160x120, the second is much smaller, the third - even smaller, the fourth is basically a single pixel and from 5 on it is nothing.
If I run without GetThumbnailImage(), the image in the picturebox moves every iteration by roughly 30 pixels in both X and Y.
Anyone ever run into this before?
HELP!
Ron
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Quote:
Originally Posted by
gigemboy
replaced all the API declarations with the correct working ones
Nice job. I stepped in looking to remember how we used to do it in previous versions, and then I remembred the main matter: using unmanaged code (=calling Api directly somewhere in code) steal one of the main goals of a framework like Net: portability.
Indeed there was not other way to do it in 1.0 and, i do belive, in 1.1. since 2.0 we all are a bit more lucky and we can grab screen easier in a managed mode.
an easy example - nothing to compare with the wonderful job of gigemboy - :
a form ("frmCapture"), two buttons ("btnWholeScreen", "btnThisForm") a pictureBox ("picCaptured") to show result is acquired (or you can save to a file).
Code:
Public Class frmCapture
Private Sub frmCapture_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
picCaptured.SizeMode = PictureBoxSizeMode.StretchImage
End Sub
Private Sub btnWholeScreen_Click(sender As System.Object, e As System.EventArgs) Handles btnWholeScreen.Click
Dim Bmp As Bitmap = GetPicture(My.Computer.Screen.Bounds, New Point(0, 0))
'Bmp.Save("C:\CapturedScreen.png")
picCaptured.Image = Bmp
End Sub
Private Sub btnThisForm_Click(sender As System.Object, e As System.EventArgs) Handles btnThisForm.Click
Dim Bmp As Bitmap = GetPicture(Me.Bounds, New Point(Me.Left, Me.Top))
'Bmp.Save("C:\CapturedForm.png")
picCaptured.Image = Bmp
End Sub
Private Function GetPicture(bounds As Rectangle, upleftSource As Point) As Bitmap
Dim retBmp As New Bitmap(bounds.Width, bounds.Height)
Dim G As Graphics = Graphics.FromImage(retBmp)
G.CopyFromScreen(upleftSource, New Point(0, 0), bounds.Size, CopyPixelOperation.SourceCopy)
G.Dispose()
Return retBmp
End Function
-
How do you draw area with mouse?
I can easily get the form or whole desktop captured. What I'm having an issue with is being able to select the area to capture with the mouse. I'm very surprised that hasn't been covered in this thread.
Can someone please post code to capture the screen that you select by drawing a box with the mouse?
Thanks in advance
Schrady
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
A trick to capture a region could be: make the whole screen capture, then show that picture and let user use the mouse to get a portion of it. It seems to me PickPick (a free utility to do that job among others) uses that logic.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
screen capture code :
Code:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim screenBounds = Screen.PrimaryScreen.Bounds
Dim screenShot As New Bitmap(screenBounds.Width, screenBounds.Height)
Using g = Graphics.FromImage(screenShot)
g.CopyFromScreen(screenBounds.Location, Point.Empty, screenBounds.Size)
End Using
PictureBox1.Image = screenShot
'Dim filePath = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyPictures, "ScreenShot.bmp")
'screenShot.Save(filePath, Imaging.ImageFormat.Bmp)
End Sub
End Class
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
If you want to use some screen recording software to help you record movement on screen, you should choose the right program. The one I used can help me capture whatever streaming video and audio files on screen with high quality, and it will also help me save it to standard video file. And you'll be able to upload your tutorial video to video sharing website or share with your friends.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
This is a strange error:
I am using this library to capture the contents of a web browser which is in another window.
First, I find the window using this:
For Each p As Process In Process.GetProcesses
If p.MainWindowTitle = "whatever" Then
handle = p.MainWindowHandle
Next
I can then look at the image with this:
Dim sc As New ScreenCapture
Dim bmp As Bitmap = CType(sc.CaptureWindow(handle), Bitmap)
The odd thing is that the image I get is of a RECENT window state, but not the current state. For example, suppose I go to a web page with a form on it and click submit and then get a response, AND THEN run the code above. The resulting bmp contains an image of the screen from BEFORE I clicked submit.
I am running vista. Any thoughts?
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
I have been using this for awhile and just recently I have decided to test the speed of it. I am capturing a window (480, 320) that runs at 60fps. I found using this test that, even though I capture twice immediately after each other, the captures are not always exactly the same. Below is the code I used. It's about as fast as I can make it.
Notice the two calls to CaptureWindowRegion. They happen right after each other. No other code or delays between them. 60fps means that each frame takes 16 milliseconds. This code finished an iteration in an average of 20 milliseconds, but most of that time is spent comparing the bitmaps.
My question is: Are there any updated function in the newest version of .NET that could speed this capturing process up? Any way to upgrade this code to be faster?
Stats for this code:
- Iterations: 5000
- Mismatches: 252
- Mismatch Percent: 5.04
- Time to complete: 104780.9931 (milliseconds)
Here is the test code I used.
vb Code:
Friend Sub test()
While Loaded
' If the VBA hasn't been attached to yet, it has closed or the WRAM or IRAM are not set...
If proc Is Nothing OrElse proc.HasExited Then
For Each p As Process In Process.GetProcesses
If p.MainWindowTitle.Contains("VisualBoyAdvance") Then
' Found VBA. Open it with full access.
proc = p
hWnd = p.MainWindowHandle
hProcess = OpenProcess(&H1F0FFF, False, p.Id)
Exit For
End If
Next
time = Date.Now ' Start time excluding time looking for the process.
Else
If cbCapture.Checked Then
' Make we sill have the window handle then grab the screen.
If hWnd = IntPtr.Zero Then
hWnd = proc.MainWindowHandle
Else
bmptemp = New Bitmap(240, 160)
bmptemp2 = New Bitmap(240, 160)
' Grab the screen twice.
bmpSrcBig = sc.CaptureWindowRegion(hWnd, New Rectangle(8, 50, 480, 320))
bmpSrcBig2 = sc.CaptureWindowRegion(hWnd, New Rectangle(8, 50, 480, 320))
' Draw the screen grabs to another bitmap, shrinking them to normal size.
Using g As Graphics = Graphics.FromImage(bmptemp)
g.InterpolationMode = Drawing2D.InterpolationMode.Bilinear
g.DrawImage(bmpSrcBig, 0, 0, 240, 160)
End Using
Using g As Graphics = Graphics.FromImage(bmptemp2)
g.InterpolationMode = Drawing2D.InterpolationMode.Bilinear
g.DrawImage(bmpSrcBig2, 0, 0, 240, 160)
End Using
' Lock the bits.
bmpDataA = bmptemp.LockBits(VBAScreenRect, ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb)
bmpDataB = bmptemp2.LockBits(VBAScreenRect, ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb)
' Check if they are not identical.
Check()
' Unlock the bits.
bmptemp.UnlockBits(bmpDataA)
bmptemp2.UnlockBits(bmpDataB)
' Increase iteration, display percentage and check if we are finished.
SetText(Me, (mismatch / iteration) * 100 & " | " & Date.Now.Subtract(time).TotalMilliseconds)
If iteration = 5000 Then
sb = New StringBuilder
sb.Append("Iterations: ")
sb.AppendLine(iteration)
sb.Append("Mismatches: ")
sb.AppendLine(mismatch)
sb.Append("Mismatch Percent: ")
sb.AppendLine((mismatch / iteration) * 100)
sb.Append("Time to complete: ")
sb.Append(Date.Now.Subtract(time).TotalMilliseconds)
MessageBox.Show(sb.ToString)
Exit Sub
End If
iteration += 1
End If
End If
End If
End While
End Sub
Friend Sub Check()
For y1 As Int32 = 0 To 159
For x1 As Int32 = 0 To 239
If Marshal.ReadInt32(bmpDataA.Scan0, (bmpDataA.Stride * y1) + (4 * x1)) <> _
Marshal.ReadInt32(bmpDataB.Scan0, (bmpDataB.Stride * y1) + (4 * x1)) Then
mismatch += 1
Exit Sub
End If
Next
Next
End Sub
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Troy-
Does that code work for an INACTIVE window, one that is hidden behind another window?
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Quote:
Originally Posted by
mankowitz
Troy-
Does that code work for an INACTIVE window, one that is hidden behind another window?
Yes.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Did you ever find a solution for Windows 7 saving it as a black image?
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
I have 2 monitors and i am getting black capture from one of them (not the primary).
If i define a rectangle that spans from monitor 1 to monitor 2 i am getting black for the portion of the secondary monitor and the normal contents from the primary one.
What i have to do to the class to get correct results?
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
I define the rectangle by :
vb Code:
myRect.Location = Me.Location
myRect.Height = Me.Height
myRect.Width = Me.Width
Me is a transparent form...
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
it seems CaptureScreen gets only the primary screen...
Any way to capture all desktop?
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Hi! First of all I just wanted to say thanks for this wonderful piece of code. There is one thing I'm having troubles, though. I am trying to take a take a screenshoot of a message box of a game, but for some reason it only takes a screenshoot of the game but ignores the message box. It works perfect on windows 7, but it does not work on windows XP.
Here's a picture:
http://imageshack.us/photo/my-images...blewindow.png/
Any thoughts?
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Also, if it helps... The problem also occurs whenever I disable Aero in Windows 7.
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
So what I need to get this working? pictureboxes? buttons?
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
The only way I have been able to get around getting black screenshots is to disable desktop composition by right clicking the exe and going to properties and ticking it then applying and saving, however in windows 8 this option is gone I hope that helps with users on win7 however is their a way with code to force an application in win8 to disable desktop composition?
-
Re: Easy Screen Capture Class - Capture Screen, Desktop Region, Form, or Controls
Oh man, this is a nice piece of code here. Kudos!