PixelChecksum() - Generates checksum for a region of pixels

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

PixelChecksum() - Generates checksum for a region of pixels

31 Aug 2014, 19:00

Note: Try the newer version : ScrCmp()
 
 

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!
My Scripts and Functions: V1  V2
User avatar
SKAN
Posts: 1551
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: 8951
Joined: 29 Sep 2013, 17:08
Location: Canada
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? :)
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
SKAN
Posts: 1551
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: 8951
Joined: 29 Sep 2013, 17:08
Location: Canada
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?
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
guest3456
Posts: 3463
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

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: 3463
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: 1551
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: 1551
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: 5
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.
mako
Posts: 2
Joined: 31 Oct 2020, 06:18

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

02 Nov 2020, 10:14

@SKAN
were there any changes to remove the randomness of this function?
it works in both ways with pixel area change and randomly without any change
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

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

02 Nov 2020, 11:56

mako wrote:
02 Nov 2020, 10:14
@SKAN
were there any changes to remove the randomness of this function?
it works in both ways with pixel area change and randomly without any change
It works fine for me.
Anyways, this function isn't CPU friendly. I wrote it as somebody requested for autoit's PixelCheckSum()
 
I will post a better function soon. Thanks.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

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

03 Nov 2020, 01:04

mako wrote:
02 Nov 2020, 10:14
@SKAN
were there any changes to remove the randomness of this function?
it works in both ways with pixel area change and randomly without any change
 
There is nothing random about this function. It detects when pixel changes.
Since I'm not able to reproduce this behavior, I'm just guessing here:
All windows (including controls) occasionally paint themselves after erasing their background.
Sometimes, this might cause flicker and while this flicker might not be visible to bare eyes, the function would detect it as a change.
I will post a different function that will take into account any flicker through a sleep duration.

@mako
Edit: New/Alternative version : ScrCmp()

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: Chunjee, gwarble and 65 guests