Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

In-memory Window Capture


  • Please log in to reply
24 replies to this topic
Xander
  • Members
  • 140 posts
  • Last active: Nov 13 2007 08:31 PM
  • Joined: 23 Sep 2007
The following script allows you to create a capture of a window in memory and read information from that window as opposed to reading it from the screen. Reading from the screen is not only unreliable (overlapping windows) but it is also slower. Also, the window doesn't need to be visible in order to get a capture of it, but it cannot be minimized.

Download: Display.ahk

Functions in v0.1:
Display_CreateWindowCapture(device, context, pixels [, id])
Display_DeleteWindowCapture(device, context, pixels)
Display_GetPixel(context, x, y)
Display_PixelSearch(x, y, w, h, color, variation [, id])
Display_FindPixelHorizontal(x, y, w, h, color, variation, context)
Display_FindPixelVertical(x, y, w, h, color, variation, context)
Display_FindText(x, y, w, h, color, variation, context)
And other functions mainly for internal useage.

Also provided is a shell function to read text (Display_ReadArea), but it is without any mappings. Therefore it won't read anything as-is (you must provide the mappings).
Display_ReadArea(x, y, w, h, color, variation, id, maxwidth, exclude)

Also, besides specifying colors in BGR format, you can also use any of the following:
BlueBackground, BlueForeground, GreenBackground, GreenForeground, RedBackground, RedForeground
CyanBackground, CyanForeground, YellowBackground, YellowForeground, VioletBackground, VioletForeground
DarkBackground, DarkForeground, LightBackground, LightForeground


BoBo¨
  • Guests
  • Last active:
  • Joined: --
Sounds promising. :D
Would you mind to advise the crowd that you've commented the script in detail within the code. That might be of help/interest for those who won't be able to catch its concept on-the-fly.
Thx for listening & for sharing it.
Keep things going.

8)

HuBa
  • Members
  • 175 posts
  • Last active: Feb 13 2012 09:51 AM
  • Joined: 24 Feb 2007
Really promising!

I haven't tested it yet but it looks like it can capture frames from a webcam or any other video source too. Or maybe from another user session.

But as I see you save the bitmap pixel-by-pixel so it is not a fast one.

Xander
  • Members
  • 140 posts
  • Last active: Nov 13 2007 08:31 PM
  • Joined: 23 Sep 2007

Would you mind to advise the crowd that you've commented the script in detail within the code. That might be of help/interest for those who won't be able to catch its concept on-the-fly.

Ahh yes, I forgot to mention that the details of which each function does, as well as well as a description of each parameter is in the source code.

Now it should be know :wink:

Xander
  • Members
  • 140 posts
  • Last active: Nov 13 2007 08:31 PM
  • Joined: 23 Sep 2007

I haven't tested it yet but it looks like it can capture frames from a webcam or any other video source too.

I haven't really tested it much other than normal application windows that I use it for so I don't know if that will work or not.

But as I see you save the bitmap pixel-by-pixel so it is not a fast one.

This script doesn't "save" anything, it just creates an image of a window in memory from which information can be obtained. I use it to test if a button is in a certain state or is visible and whatnot as well as to read numbers from a window that can otherwise not be obtained (window paints its own buttons or text etc...)

The Display_ReadArea function was 5x faster when using the window capture method as opposed to reading the pixels directy from the screen...

Ile
  • Guests
  • Last active:
  • Joined: --

Display_ReadArea(x, y, w, h, color, variation, id, maxwidth, exclude)


Does this read any text or just the characters "$.,0123456789"?

If just those characters, is there a way to make it read normal text (a-z) as well?

Thanks.

thewer
  • Members
  • 13 posts
  • Last active: Mar 12 2010 08:16 AM
  • Joined: 12 Feb 2008
Hi there,

Thanks for your code - it really helped me understanding a lot of things about GDI...
Still I got some problems with it -

what I'm trying to do:
I want to make screenshots of a certain window every ** minutes and save these images as *.png.
This kind of works, except:
- The code I'm using doesn't make a shot of the actual window, but of the desktop at the window coordinates. So if this window isn't the top/active one, the images I get are from the windows overlapping the one I want.
- Sometimes the screen area seems to be messed up - although I'm giving the right coordinates (nL, nT, nW, nH), they sometimes(!) don't seem to fit...

I think my problem either lies in the definition of hDC or mDC, not sure so...

I also tried to create the hBM not as CompatibleBitmap but as CreateDIBSection, but the result is absolutely the same, CreateCompatibleBitmap just seems to be the easieer way. Instead of your "PrintWindow" I'm using "BitBlt" as shown in this thread (<!-- m -->http://www.autohotke...topic18146.html<!-- m -->) to copy the color values - this could of course be the reason for mixing up coordinates, but I looked all commands up in the MS GDI help, and it seems to be used the right way...
I know the window doesn't have to be minimized, but I thought just being in the back should work (another funny bug is, when part of the window is off the screen - then the image is all black).

Sorry for bothering, just can't figure it out on my own...
Thanks for your help!

{
	if !id
		WinGet, id, ID
	hDC := DllCall("GetDC", UInt, id)
	WinGetPos, nL, nT, nW, nH, ahk_id %id%
	WinGetTitle, this_title, ahk_id %id%
	mDC := DllCall("gdi32.dll\CreateCompatibleDC", "Uint", hDC)
	hBM := DllCall( "gdi32.dll\CreateCompatibleBitmap" , "uint", hDC, "int", nW, "int", nH )
	DllCall("gdi32.dll\SelectObject", "Uint", mDC, "Uint", hBM)
	DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020)	
	sFile = %this_title%_%time%.png
	Convert(hBM, sFile) ;Function for saving image as png
	DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
	DllCall("DeleteDC", "Uint", mDC)
	DllCall("DeleteObject", "Uint", hBM) 
}


yocy11
  • Guests
  • Last active:
  • Joined: --

The following script allows you to create a capture of a window in memory and read information from that window as opposed to reading it from the screen. Reading from the screen is not only unreliable (overlapping windows) but it is also slower. Also, the window doesn't need to be visible in order to get a capture of it, but it cannot be minimized.

Download: Display.ahk

Functions in v0.1:

Display_CreateWindowCapture(device, context, pixels [, id])
Display_DeleteWindowCapture(device, context, pixels)
Display_GetPixel(context, x, y)
Display_PixelSearch(x, y, w, h, color, variation [, id])
Display_FindPixelHorizontal(x, y, w, h, color, variation, context)
Display_FindPixelVertical(x, y, w, h, color, variation, context)
Display_FindText(x, y, w, h, color, variation, context)
And other functions mainly for internal useage.

Also provided is a shell function to read text (Display_ReadArea), but it is without any mappings. Therefore it won't read anything as-is (you must provide the mappings).
Display_ReadArea(x, y, w, h, color, variation, id, maxwidth, exclude)

Also, besides specifying colors in BGR format, you can also use any of the following:
BlueBackground, BlueForeground, GreenBackground, GreenForeground, RedBackground, RedForeground
CyanBackground, CyanForeground, YellowBackground, YellowForeground, VioletBackground, VioletForeground
DarkBackground, DarkForeground, LightBackground, LightForeground


How do I get "OutputVar" from this code to a MsgBox?

skyd1v3r
  • Members
  • 73 posts
  • Last active: Apr 18 2010 11:42 AM
  • Joined: 18 Jun 2009
Hello,

I got this link as answer to this post:

"Is there a way to cache files used for imagesearch?
You could cache the files on the disk into ram, and cache the created screenshot for several calls. (I commonly search for about 100 files on a single screen. It makes little sense to let AHK create a new screenshot every time.)"


How can this be achived with the code above?

Thanks a lot in advance !

Cheers.

Splash
  • Members
  • 5 posts
  • Last active: Jul 27 2009 02:34 AM
  • Joined: 16 Dec 2008
You can try DirectX API to get the content of a minimized window. :)

Guest777
  • Guests
  • Last active:
  • Joined: --
Hi,

I've been using the Display.ahk and it works great. I just have one question (and I can't seem to find the answer by searching) on allocating the memory that gets passed. Currently I'm using it as follows:

device =
context =
pixels =

Display_CreateWindowCapture(device, context, pixels, id)
currentPoint1c := Display_GetPixel(context,testPoint1x,testPoint1y)
Display_DeleteWindowCapture(device, context, pixels)

The script works, but I think it's slowly leaking memory as things tend to slow down after many hours.

Do I need the first 3 lines of that code? Or should I be allocating / freeing memory in some other way before passing to CreateWindowCapture?

Thanks for any help!!!

Snoobish
  • Members
  • 3 posts
  • Last active: Feb 11 2010 10:04 PM
  • Joined: 09 Feb 2010
Trying to get a pixel using this code.

Numpad7::
id = (id of my window)
Display_CreateWindowCapture(device, context, pixels, id)
SpecificColor := Display_GetPixel(context, 26, 445)
MsgBox %SpecificColor%
Display_DeleteWindowCapture(device, context, pixels)
return

However the MsgBox returns 0 instead of the BGR color.

Any help is greatly appreciated.

ash0803
  • Members
  • 7 posts
  • Last active: Dec 30 2010 03:23 PM
  • Joined: 27 Jun 2010

Hi,

I've been using the Display.ahk and it works great. I just have one question (and I can't seem to find the answer by searching) on allocating the memory that gets passed. Currently I'm using it as follows:

device =
context =
pixels =

Display_CreateWindowCapture(device, context, pixels, id)
currentPoint1c := Display_GetPixel(context,testPoint1x,testPoint1y)
Display_DeleteWindowCapture(device, context, pixels)

The script works, but I think it's slowly leaking memory as things tend to slow down after many hours.

Do I need the first 3 lines of that code? Or should I be allocating / freeing memory in some other way before passing to CreateWindowCapture?

Thanks for any help!!!


Did you ever get this sorted??? I also think (certain) its leaking memory as I am checking about 16-20 items every second and can see the memory used climb up slowly until the computer is unusable.

It is directly related to this code.

Display_CreateWindowCapture(device, context, pixels , this_stack_id)
			pix_color:=Display_GetPixel(context, fold_button_x_coord, fold_button_y_coord)
      Display_DeleteWindowCapture(device, context, pixels)

Any help?

guest3456
  • Guests
  • Last active:
  • Joined: --
leaked memory for me too a while back

ash0803
  • Members
  • 7 posts
  • Last active: Dec 30 2010 03:23 PM
  • Joined: 27 Jun 2010

leaked memory for me too a while back


Thanks for letting me know its not an isolated problem.

Anybody any ideas on how to fix this??