PixelChecksum() - Generates checksum for a region of pixels

Post your working scripts, libraries and tools
User avatar
SKAN
Posts: 319
Joined: 29 Sep 2013, 16:58

PixelChecksum() - Generates checksum for a region of pixels

31 Aug 2014, 19:00

Code: Select all

/*   __    __  __          __ __       __    __                 _       __                   
    / /_  / /_/ /_____  _ / // /____ _/ /_  / /________________(_)___  / /_ ____  _______
   / __ \/ __/ __/ __ \(_) // // __ '/ __ \/ //_/ ___/ ___/ __/ / __ \/ __// __ \/ __/ _ \
  / / / / /_/ /_/ /_/ / / // // /_/ / / / / ,< (__  ) /__/ / / / /_/ / /__/ /_/ / / / // / 
 /_/ /_/\__/\__/ .___(_) // / \__,_/_/ /_/_/|_/____/\___/_/ /_/ .___/\__(_)____/_/  \__ /  
              /_/     /_//_/                                 /_/                   (___/   
 
 http://ahkscript.org/boards/viewtopic.php?&t=4431
__________________________________________________________________________________________
*/

PixelCheckSum( X, Y, W, H, Title := "" ) { ;               By SKAN,   http://goo.gl/X5dfvn
;                                                          CD:08/Jun/2009 | MD:01/Sep/2014

  Static DIBSECTION, SRCCOPY := 0x00CC0020, CAPTUREBLT := 0x40000000, BPP := 32
  Local hWnd, hDC, mDC, hBM, oBM, nSize, pBITMAPINFOHEADER, ppvBits := 0
  
  If not VarSetCapacity( DIBSECTION )
         VarSetCapacity( DIBSECTION, 104, 0 ) 
  
  pBITMAPINFOHEADER := &DIBSECTION + ( A_PtrSize = 4 ? 24 : 32 )
  
  NumPut(  40, pBITMAPINFOHEADER +  0, "UInt"   ) 
  NumPut(   W, pBITMAPINFOHEADER +  4, "UInt"   )
  NumPut(   H, pBITMAPINFOHEADER +  8, "UInt"   )
  NumPut(   1, pBITMAPINFOHEADER + 12, "UShort" )
  NumPut( BPP, pBITMAPINFOHEADER + 14, "UShort" )

  hWnd  := WinExist( Title )
  hDC   := DllCall( "GetDC", "Ptr",hWnd, "UPtr" )
  mDC   := DllCall( "CreateCompatibleDC", UInt,hDC, "UPtr" )

  hBM   := DllCall( "CreateDIBSection", "Ptr", mDC, "Ptr", pBITMAPINFOHEADER, "Int",0
                                      , "PtrP",ppvBits, "Ptr",0, "Int",0, "UPtr" )
  
  oBM   := DllCall( "SelectObject", "Ptr",mDC, "Ptr",hBM, "UPtr" )
  
  DllCall( "BitBlt", "Ptr",mDC, "Int",0, "Int",0, "Int",W, "Int",H, "Ptr",hDC
                   , "Int",X, "Int",Y, "UInt",SRCCOPY | CAPTUREBLT )

  DllCall( "SelectObject", "Ptr",mDC, "Ptr",oBM )
  DllCall( "DeleteDC",  "Ptr",mDC )
  DllCall( "ReleaseDC", "Ptr",hWnd, "Ptr",hDC )

  DllCall( "GetObject", "Ptr",hBM, "Int",( A_PtrSize = 4 ? 84 : 104 ), "Ptr",&DIBSECTION )
  nSize := NumGet( pBITMAPINFOHEADER + 20, "UInt" ) 
  
Return DllCall( "NTDLL\RtlComputeCrc32", "UInt",0, "Ptr",ppvBits, "UInt",nSize, "UInt" )
     , DllCall( "DeleteObject", "Ptr",hBM )    
}
Test:

Code: Select all

; Example - Wait for a Screen Region to change

ChkSum := PixelChecksum( 0,0,32,32 )

While % ( ChkSum = PixelChecksum( 0,0,32,32 ) )
   Sleep, 100
MsgBox, Screen Region Change Detected!
User avatar
joedf
Posts: 6487
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada, Quebec
Contact:

Re: PixelChecksum() - Generates checksum for a region of pix

31 Aug 2014, 19:06

Speed tests? :o
User avatar
SKAN
Posts: 319
Joined: 29 Sep 2013, 16:58

Re: PixelChecksum() - Generates checksum for a region of pix

31 Aug 2014, 19:25

joedf wrote:Speed tests? :o
Not yet, only tested for leaks. Got tired of toggling between XP, Win 7, Win 7 x64, Win 8.1, Win 8.1 x64.
It is an old function I wrote ( and forgotten ) and today there was a request for x64 compatibility.

Note: Speed can be improved if CAPTUREBLT is avoided and BPP is set to 16.
User avatar
joedf
Posts: 6487
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada, Quebec
Contact:

Re: PixelChecksum() - Generates checksum for a region of pix

31 Aug 2014, 20:24

Ahh I see... What is CAPTUREBLT, if I may ask? :)
User avatar
SKAN
Posts: 319
Joined: 29 Sep 2013, 16:58

Re: PixelChecksum() - Generates checksum for a region of pix

31 Aug 2014, 20:30

joedf wrote:Ahh I see... What is CAPTUREBLT, if I may ask? :)
I am myself not clear, but I guess with CAPTUREBLT, BitBlt will see a semi transparent layered window covering the target area.
User avatar
joedf
Posts: 6487
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada, Quebec
Contact:

Re: PixelChecksum() - Generates checksum for a region of pix

31 Aug 2014, 20:47

Ah ok, so if I understand correctly, this is only for Aero/transparent-window supported OS?
guest3456
Posts: 2419
Joined: 09 Oct 2013, 10:31

Re: PixelChecksum() - Generates checksum for a region of pix

01 Sep 2014, 02:26

joedf wrote:Ah ok, so if I understand correctly, this is only for Aero/transparent-window supported OS?
no, the bitblt call should work even with the dwm (aero) disabled

User avatar
joedf
Posts: 6487
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada, Quebec
Contact:

Re: PixelChecksum() - Generates checksum for a region of pix

01 Sep 2014, 03:30

Ah ok..
durschtnase
Posts: 3
Joined: 11 Sep 2014, 11:50

Re: PixelChecksum() - Generates checksum for a region of pix

11 Sep 2014, 11:56

first of all.. great script!

but cant get this to work within an #IfWinActive block
the checksum is always different the second time
without such an block its fine

any ideas?
guest3456
Posts: 2419
Joined: 09 Oct 2013, 10:31

Re: PixelChecksum() - Generates checksum for a region of pix

11 Sep 2014, 13:16

guest3456 wrote:
joedf wrote:Ah ok, so if I understand correctly, this is only for Aero/transparent-window supported OS?
no, the bitblt call should work even with the dwm (aero) disabled
actually upon further thought, i'm not completely sure about this, best to test

User avatar
SKAN
Posts: 319
Joined: 29 Sep 2013, 16:58

Re: PixelChecksum() - Generates checksum for a region of pix

11 Sep 2014, 14:27

durschtnase wrote:first of all.. great script!
Thanks. Welcome to the forum. :)
cant get this to work within an #IfWinActive block
the checksum is always different the second time
Can you post a snippet for me to work/test with?
durschtnase
Posts: 3
Joined: 11 Sep 2014, 11:50

Re: PixelChecksum() - Generates checksum for a region of pix

11 Sep 2014, 18:43

of course! here it is:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#Include PixelCheckSum.ahk ; the script you provided

#IfWinActive ahk_class Notepad ; notepad windows 7

#o::
	ChkSum := PixelChecksum(0,0,100,100)
	SetTimer Monitor, 500
return	

Monitor:
	ChkSum2 := PixelChecksum(0,0,100,100)
	if (ChkSum != ChkSum2) {
		MsgBox, changes deteted.
		SetTimer Monitor, off
	}
return

#IfWinActive
Win+O to activate the timer
comment out the #IfWinActive at the beginning and at the end and you get different behavior

commented out:
- after pressing Win+O and moving an icon into the topleft corner of the desktop i get the MsgBox

not commented out:
- after opening and activating notepad i press Win+O and get the MsgBox without moving something to the topleft corner

hope you can reproduce this behavior

p.s.: when i specify a window title as 5th parameter to your function this problem does not occur
User avatar
SKAN
Posts: 319
Joined: 29 Sep 2013, 16:58

Re: PixelChecksum() - Generates checksum for a region of pix

11 Sep 2014, 18:56

durschtnase wrote:p.s.: when i specify a window title as 5th parameter to your function this problem does not occur
Problem solved then!. Simply pass ahk_id as the 5th parameter!

:?:

Edit:

Something like this ( untested )

Code: Select all

#o::
    notepadID := WinExist()
    ChkSum := PixelChecksum(0,0,100,100, "ahk_id " notepadID )
    SetTimer Monitor, 500
return  

Monitor:
    ChkSum2 := PixelChecksum(0,0,100,100, "ahk_id " notepadID )
    if (ChkSum != ChkSum2) {
        MsgBox, changes deteted.
        SetTimer Monitor, off
    }
return
durschtnase
Posts: 3
Joined: 11 Sep 2014, 11:50

Re: PixelChecksum() - Generates checksum for a region of pix

11 Sep 2014, 19:03

yap..
thanks for having me write this snippet.. thats when i tried and found out ;)
though a bit strange behaviour ;)
peter

Re: PixelChecksum() - Generates checksum for a region of pixels

09 Jun 2016, 16:04

Hi,
I am trying the code you have provided and it acts all random. For example, I am monitoring a part of a still screenshot. Each time the check sum turns out to be different yet nothing changes. :?:
PhantomBoy27
Posts: 4
Joined: 15 Aug 2018, 13:42

Re: PixelChecksum() - Generates checksum for a region of pixels

23 Sep 2018, 13:04

Hi!
Great script!! :thumbup: :clap:
But I need one more thing: How is that possible to get the coordinates where the change happened?
MsgBox, %X% %Y% and %W% %H% doesn't work in this case.

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 16 guests