Jump to content

Recommended Posts

Posted (edited)

While looking for a way to recognize text when the background color changes, I wrote the following function which calculates the ADLER checksum for an area which takes into count only the pixels of a certain color, ignoring the rest ( but it can be easily extended to compute the checksum for more that one color ) :

Func PixelColorChecksum( $iColor, $iLeft, $iTop, $iRight, $iBottom )

    Local Const $iMOD_ADLER = 65521
    Local $iA = 1, $iB = 0, $iRow, $iCol
;   Local $sStr = ""

    For $iRow = $iTop to $iBottom
        For $iCol = $iLeft To $iRight
            If PixelGetColor( $iCol, $iRow ) = $iColor Then
                $iA = Mod( $iA + ( $iCol - $iLeft + 1 ) + ( $iRow - $iTop ) * ( $iRight - $iLeft + 1 ), $iMOD_ADLER )
                $iB = Mod( $iB + $iA, $iMOD_ADLER )
;               $sStr = $sStr & "#"
;           Else
;               $sStr = $sStr & "."
            EndIf
        Next
;       $sStr = $sStr & @LF
    Next

;   ConsoleWrite( $sStr & @CRLF)

    Return BitOR( BitShift($iB, -16), $iA) - 1

EndFunc

The above code was taken/adapted from http://en.wikipedia.org/wiki/Adler-32#Example_implementation and extra checks are ignored.

When looking at the PixelChecksum's help, it is said that "Previous versions were extremely slow, however the function is now significantly faster. " thus I believe this function can be also faster by writing the code in C.

My question : where can I find the source code for the PixelChecksum function ?

Edited by Drin
  • Moderators
Posted

Drin,

You cannot see the source as the Devs have not released it for the past several versions. :mellow:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Posted (edited)

The example below will calculate the checksum of the rectangle surrounding the File option in the Menu :

ConsoleWrite( "0x" & Hex( PixelColorChecksum( 0x000000, 4, 22, 22,32 ), 8 ) & @CRLF )

Func PixelColorChecksum( $iColor, $iLeft, $iTop, $iRight, $iBottom )

    Local Const $iMOD_ADLER = 65521
    Local $iA = 1, $iB = 0, $iRow, $iCol
    Local $sStr = ""

    For $iRow = $iTop to $iBottom
        For $iCol = $iLeft To $iRight
            If PixelGetColor( $iCol, $iRow ) = $iColor Then
                $iA = Mod( $iA + ( $iCol - $iLeft + 1 ) + ( $iRow - $iTop ) * ( $iRight - $iLeft + 1 ), $iMOD_ADLER )
                $iB = Mod( $iB + $iA, $iMOD_ADLER )
               $sStr = $sStr & "#"
           Else
               $sStr = $sStr & "."
            EndIf
        Next
       $sStr = $sStr & @LF
    Next

    ConsoleWrite( $sStr & @CRLF)

    Return BitOR( BitShift($iB, -16), $iA) - 1

EndFunc

Result :

...................
..........#........
..#####.#.#........
..#.......#........
..#.....#.#..###...
..#####.#.#.#...#..
..#.....#.#.#####..
..#.....#.#.#......
..#.....#.#.#...#..
..#.....#.#..###...
...................


0x92891520
Edited by Drin
Posted (edited)

0x00000001 is the result when the searched color is NOT found - I admit it would be clear if return would be 0.

EDIT : I changed the return value - 0 when no pixels are found !

When running the example, I'm applying this function to the area around the File option in the menu, as seen in the below pic :

Posted Image

JohnOne, are you getting any '#' signs in your STDOUT ?

Hex is not required but in my case I can read it easier than an int and the length is consistent.

Edited by Drin
Posted (edited)

On my machine ConsoleWrite( "0x" & Hex( PixelColorChecksum( 0x000090, 77, 67, 161, 76 ), 8 ) & @CRLF ) will return the checksum of the first part of the line which is the same even if the line is highlighted or not ( different background ) :

.....................................................................................
...####..............................####.........####.#####.......##....##..........
..##..#................................##..........##...##...............##..........
..#...#...###..######...####...###.....##....###...####.#####.##.####...#####...###..
.##......##.##..##..##.##..#..##.##....##...#..##..#.##.##.###.....##....##....#..##.
.##.....##..##..##..##.###...##..##...##...######.###.#.#..##......##....##...######.
.##.....##..##.##..##...###..##..##...##...##.....###.###.##......##....##....##.....
.##...#.##..#..##..##.#..##..##..#....##...##...#.###.###.##......##....##..#.##...#.
..####...###..####.#######....###...######..####..##..##.#####..######..####...####..
.....................................................................................

0x135B0E02

Edited by Drin
Posted (edited)

Tried with a few different themes set, and the closes I came was with classic. win 7 32

.....................
..####.....#.........
..#........#.........
..#........#.........
..#.....#..#....#....
..####..#..#.........
..#.....#..#..####...
..#.....#..#..#......
..#.....#..#.........
..#.....#..#....#....
.....................
0xF1D910F9

Maybe screen resolution plays a part.

Pretty good idea by the way.

EDIT:

No it wasent, that was windows basic, this is classic

...................
..........#........
..#####.#.#........
..#.......#........
..#.....#.#..###...
..#####.#.#.#...#..
..#.....#.#.#####..
..#.....#.#.#......
..#.....#.#.#...#..
..#.....#.#..###...
...................

0x92891520

EDIT2:

...........................................................................................................................................................................................................................................................................................................................................................................................
..........#.............................#..............................................#.....................................................................#...........................................................................................................................................##..##.........................................#..................................
..#####.#.#...................#####.....#.#.#................####......................#.................#...#.#...........................#####.............#....................###.........#...#..............................#..........................................................####........#...#..............................#....#.......#..................................
..#.......#...................#.........#...#...............#..........................#.................#...#...............................#...............#...................#...#........#..................................#..........................................................#...#.......#...#..............................#....#.......#..................................
..#.....#.#..###..............#......####.#.###.............#......###...###..#.#..###.####..............#...#.#..###..#..#..#...............#....###...###..#..###.............#.....#.####..###.#..###..####...###.............#.....###..####...####.#...#..###...####..###..............#...#.#...#.###.###..###..#.#..###.............#....#..###..#.####.............................
..#####.#.#.#...#.............####..#...#.#.#................###..#...#.....#.##..#....#...#..............#.#..#.#...#.#..#..#...............#...#...#.#...#.#.#................#.....#.#...#.#...#.#...#.#...#.#................#........#.#...#.#...#.#...#.....#.#...#.#...#.............####..#...#.#...#...#...#.##..#................######.#...#.#.#...#............................
..#.....#.#.#####.............#.....#...#.#.#...................#.#####..####.#...#....#...#..............#.#..#.#####.#.#.#.#...............#...#...#.#...#.#.##...............#.....#.#...#.#...#.#...#.#...#.##...............#.....####.#...#.#...#.#...#..####.#...#.#####.............#...#.#...#.#...#...#####.#...##...............#....#.#####.#.#...#............................
..#.....#.#.#.................#.....#...#.#.#...................#.#.....#...#.#...#....#...#..............#.#..#.#.....#.#.#.#...............#...#...#.#...#.#...##.............#.....#.#...#.#...#.#...#.#...#...##.............#....#...#.#...#.#...#.#...#.#...#.#...#.#.................#...#.#...#.#...#...#.....#.....##.............#....#.#.....#.#...#............................
..#.....#.#.#...#.............#.....#...#.#.#...................#.#...#.#...#.#...#....#...#...............#...#.#...#..#...#................#...#...#.#...#.#....#..............#...#..#...#.#...#.#...#.#...#....#.............#....#...#.#...#.#...#.#...#.#...#.#...#.#...#.............#...#.#...#.#...#...#...#.#......#.............#....#.#...#.#.#...#............................
..#.....#.#..###..............#####..####.#..##.............####...###...####.#....###.#...#...............#...#..###...#...#................#....###...###..#.###................###...####...##.#..###..#...#.###..............####..####.#...#..####..####..####..####..###..............####...####.#...#....###..#...###..............#....#..###..#.####.............................
........................................................................................................................................................................................#.............................................................#.................#.................................................................................#................................

0x02DB4A1A

Quite impressive really.

EDIT3:

Sorry for the multiple edits but I just keep getting more and more impressed by it.

Address bar of this topic, classic theme, firefox.

...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
...#.........................#...#............................................................................................................#..##...........................#..........................#.....................................................................................................................##............................................................#............#................#................#.........................#........................................................................
...#.....#...#...............#...#.........................................#.........#.#.................#.......#............................#.#.............................#.#...............#........#...#....###...###...###.....#.....#.......................................#.........................................#....................#...#.......................#.............#............#................#................#.........................#....#.#..............#..............###...###....#......#...###..#####..
...#.....#...#...............#...#.........................................#...........#.........................#............................#.#.............................#.#........................#..##...#...#.#...#.#...#...##....##.................................................................................#....................#.........................................#............#................#................#.........................#....#.#..............#.............#...#.#...#..##.....##..#...#.#......
...####..###.###.####...#...#...#..#..#..#.#..#..#.#..#..#......###..#...#.###..###..#.###..###..###.#.#.#.####..###......###..###..###.##...#..###..###..#.#.#...#.###.##...#..###..###..####..#..###..#....#.......#.....#.....#..#.#...#.#......####..#.#..###..####...###...###.#.####...####.....####...###..#..#..#.....###.#...#.####...###.###.#..###..####......####..#.#...#..###..#..###..###..#..###..#.#..###.####...###...###.#..#..###.#...#.###.##...#...######..###..####..###.#.#.#...#.#...#.....#...#....#.#......#.#......
...#...#.#...#...#...#..#...#...#..#..#..#.#..#..#.#..#..#.........#.#...#.#...#...#.#.#...#....#....##..#.#...#.#.......#....#...#.#..#..#..#..#...#...#.##..#...#.#..#..#..#..#...#...#.#...#.#.#.....#....#.....##.....#.....#..#..#..#..#......#...#.##..#...#.#...#.#...#.#....#.#...#.#...#.....#...#.#...#.#..#..#.....#...#...#.#...#.#....#...#.#...#.#...#.....#...#.#..#.#..#...#.#.#....#...#.#.#...#.##..#....#...#.#...#.#....#.#..#....#...#.#..#..#..#....#.#...#...#.#...#.#...##..#...#.#...#....#....#...#..#.....#..####...
...#...#.#...#...#...#......#...#..#.#.#.#.#.#.#.#.#.#.#.#......####.#...#.#...#...#.#.#...##...#....#...#.#...#.#.......#....#...#.#..#..#..#..#...#...#.#...#...#.#..#..#..#..#...#...#.#...#.#.#.....#....#.......#...#.....#...#####.#####.###.#...#.#...#...#.#...#.#...#.##...#.#...#.#...#.###.#...#.#####.#.#.#.#.###.#...#...#.#...#.#....#...#.#...#.#...#.###.#...#.#...#...#####.#.#....#...#.#.#...#.#...#....#...#.#####.#....##...##...#...#.#..#..#..#....#.#...#####.#...#.#...#....#.#...####...#.....#...#####...#.......#..
...#...#.#...#...#...#......#...#..#.#.#.#.#.#.#.#.#.#.#.#.....#...#.#...#.#...#...#.#.#.....##.#....#...#.#...#.#.......#....#...#.#..#..#..#..#...#...#.#...#...#.#..#..#..#..#...#...#.#...#.#.#.....#....#.......#..#.....#.......#.....#......#...#.#...#...#.#...#.#...#...##.#.#...#.#...#.....#...#.#.....#.#.#.#.....#...#...#.#...#.#....#...#.#...#.#...#.....#...#.#...#...#.....#.#....#...#.#.#...#.#...#....#...#.#.....#....#.#....##.#...#.#..#..#..#..######..#.....#...#.#...#....#.#......#..#......#......#...#........#..
...#...#.#...#...#...#..#...#...#...#...#...#...#...#...#...#..#...#.#...#.#...#...#.#.#......#.#....#...#.#...#.#....#..#....#...#.#..#..#..#..#...#...#.#...#...#.#..#..#..#..#...#...#.#...#.#.#.....#....#...#...#.#.....#........#.....#......#...#.#...#...#.#...#.#...#....#.#.#...#.#...#.....#...#.#...#..#...#......#...#...#.#...#.#....#...#.#...#.#...#.....#...#.#..#.#..#...#.#.#....#...#.#.#...#.#...#....#...#.#...#.#....#..#....#.#...#.#..#..#..#...#.#....#...#.#...#.#...#.....#......#..#.......#......#..#.....#...#..
...#...#..##..##.####...#..#...#....#...#...#...#...#...#...#...####..####..##..###..#..##.###...###.#...#.####...##..#...###..###..#..#..#.#...#....###..#....####.#..#..#.#....##..###..####..#..###.#....###...###..#####.#####....#.....#......####..#....###..####...###..###..#.#...#..####.....#...#..###...#...#......#....####.#...#..###..##.#..###..#...#.....####..#.#...#..###..#..###..###..#..###..#....###.#...#..###...###.#...####...####.#..#..#.#....#.#.....###..#...#..##.#.....#....##...#####..###.....#..#####..###...
.................#.........#...#...........................................................................#................................#...............................#.............#............#...........................................#...............#............................#........................................................................#..........................................................................................#................................#.........................................
.................#.........#...#...........................................................................#................................#...............................#.............#............#...........................................#...............#.........................###.........................................................................#..........................................................................................#................................#.........................................
...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

ConsoleWrite( "0x" & Hex( PixelColorChecksum( 0x000000, 114, 35, 640,47 ), 8 ) & @CRLF )

I'll stop now.

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Posted

Good work JohnOne !

For the first example you gave, I suspect you are using a theme which has ClearType enabled, thus some pixels are "blended" with the background. You can change the function to support more than one color by adding an extra check here :

Func PixelColorChecksum( $iColor, $iLeft, $iTop, $iRight, $iBottom )

    Local Const $iMOD_ADLER = 65521
    Local $iA = 1, $iB = 0, $iRow, $iCol, $iClr
    Local $sStr = ""

    For $iRow = $iTop to $iBottom
        For $iCol = $iLeft To $iRight
; new code here
            $iClr = PixelGetColor( $iCol, $iRow )
; new code here
            If $iClr = $iColor Or $iClr = 0x000000 Then              ; added black
                $iA = Mod( $iA + ( $iCol - $iLeft + 1 ) + ( $iRow - $iTop ) * ( $iRight - $iLeft + 1 ), $iMOD_ADLER )
                $iB = Mod( $iB + $iA, $iMOD_ADLER )
               $sStr = $sStr & "#"
           Else
               $sStr = $sStr & "."
            EndIf
        Next
       $sStr = $sStr & @LF
    Next

Or even better, this first parameter should be an array of colors to be matched ?

  • 1 month later...
Posted

Could definitely be useful. Too slow using PixelGetColor, but with FastFind and a few tweaks to allow color variations, it can do the following on standard Win7 menus in about half a second:

...............................................................................................................................................................................................
...####..#..#......................####......#..#.....................###........................#...................#.....#.#..............................######................#............
...#........#......................#.........#.....#.................#...........................#....................#...#....................................#..................#............
...#........#......................#.........#.....#.................#...........................#....................#...#....................................#..................#............
...#.....#..#...###................#......####..######...............##.....###..####..###..###..#####................#...#..#...###.#...#...#.................#.....###....###...#..###.......
...####..#..#..#...#...............####..#..##..#..#..................##...#...#....#..##..##....##..#................##.#...#..#...#.#..##.##.................#....#...#..#...#..#..#.........
...#.....#..#..#####...............#.....#...#..#..#....................#..#####..###..#...#.....#...#.................#.#...#..#####.#.###.#..................#....#...#..#...#..#..#.........
...#.....#..#..#...................#.....#...#..#..#....................##.#.....#..#..#...#.....#...#.................###...#..#.....###.###..................#....#...#..#...#..#...##.......
...#.....#..#..#...................#.....#..##..#..#....................#..#.....#..#..#...#.....#...#.................##....#..#.....##..##...................#....#...#..#...#..#....#.......
...#.....#..#...####...............####...####..#..###...............####...####.####..#....###..#...#..................#....#...####..#...#...................#.....###....###...#..###.......
...............................................................................................................................................................................................

#include "FastFind.au3"
#Include <Color.au3>
 
ConsoleWrite( "0x" & Hex( PixelColorChecksum( 0x000000, 5, 26, 195, 36, 205 ), 8 ) & @CRLF )
 
Func PixelColorChecksum( $iColor, $iLeft, $iTop, $iRight, $iBottom, $iVariation = 0 )
 
    Local Const $iMOD_ADLER = 65521
    Local $iA = 1, $iB = 0, $iRow, $iCol
    Local $sStr = ""
    
    FFSnapShot($iLeft, $iTop, $iRight, $iBottom)
    
    For $iRow = $iTop to $iBottom
        For $iCol = $iLeft To $iRight
            If _ColorInBounds(FFGetPixel( $iCol, $iRow ), $iColor, $iVariation) Then
                $iA = Mod( $iA + ( $iCol - $iLeft + 1 ) + ( $iRow - $iTop ) * ( $iRight - $iLeft + 1 ), $iMOD_ADLER )
                $iB = Mod( $iB + $iA, $iMOD_ADLER )
               $sStr = $sStr & "#"
           Else
               $sStr = $sStr & "."
            EndIf
        Next
       $sStr = $sStr & @LF
    Next
 
    ConsoleWrite( $sStr & @CRLF)
 
    Return BitOR( BitShift($iB, -16), $iA) - 1
EndFunc
 
 
Func _ColorInBounds(Const $iColorFound, Const $iColor, Const $iVariation)
    Local $iRedFound = _ColorGetRed($iColorFound)
    Local $iGreenFound = _ColorGetGreen($iColorFound)
    Local $iBlueFound = _ColorGetBlue($iColorFound)
 
    Local $iRed = _ColorGetRed($iColor)
    Local $iGreen = _ColorGetGreen($iColor)
    Local $iBlue = _ColorGetBlue($iColor)
 
    Local $iR = Abs($iRedFound - $iRed)
    Local $iG = Abs($iGreenFound - $iGreen)
    Local $iB = Abs($iBlueFound - $iBlue)
 
    If ($iR <= $iVariation) AND ($iG <= $iVariation) AND ($iB <= $iVariation) Then
        Return 1
    Else
        Return 0
    EndIf
EndFunc
Posted

Drin,

You cannot see the source as the Devs have not released it for the past several versions. :graduated:

M23

For those interested, for AutoIt 3.1 (taken from here). As mentioned there have probably been a lot of changes since then though.

///////////////////////////////////////////////////////////////////////////////
// PixelChecksum()
// Does an Alder32 checksum of a region of pixels
// PixelChecksum(<left>,<top>,<right>,<bottom> [,<step>])
///////////////////////////////////////////////////////////////////////////////
AUT_RESULT AutoIt_Script::F_PixelChecksum (VectorVariant &vParams, Variant &vResult)
{
int    q,r;
COLORREF  col;
HDC    hdc;
RECT   relrect;
unsigned long adler = 1L;
unsigned long s1, s2;
int    nStep = 1;
POINT   ptOrigin;
relrect.left = vParams[0].nValue();
relrect.top = vParams[1].nValue();
relrect.right = vParams[2].nValue();
relrect.bottom = vParams[3].nValue();
// Step required?
if (vParams.size() >= 5 && vParams[4].nValue() > 1)
  nStep = vParams[4].nValue();
// Convert coords to screen/active window/client
ConvertCoords(m_nCoordPixelMode, ptOrigin);
relrect.left += ptOrigin.x;
relrect.top += ptOrigin.y;
relrect.right += ptOrigin.x;
relrect.bottom += ptOrigin.y;

hdc = GetDC(NULL);
for( q=relrect.left; q<=relrect.right; q = q + nStep)
{
  for( r=relrect.top; r<=relrect.bottom; r = r + nStep)
  {
   col = GetPixel(hdc, q, r);
   s1 = adler & 0xffff;
   s2 = (adler >> 16) & 0xffff;
   s1 = (s1 + GetRValue(col)) % 65521;
   s2 = (s2 + s1) % 65521;
   adler = (s2 << 16) + s1;
   s1 = adler & 0xffff;
   s2 = (adler >> 16) & 0xffff;
   s1 = (s1 + GetGValue(col)) % 65521;
   s2 = (s2 + s1) % 65521;
   adler = (s2 << 16) + s1;
   s1 = adler & 0xffff;
   s2 = (adler >> 16) & 0xffff;
   s1 = (s1 + GetBValue(col)) % 65521;
   s2 = (s2 + s1) % 65521;
   adler = (s2 << 16) + s1;
  }
}
ReleaseDC(NULL,hdc);
vResult = (double)adler;
return AUT_OK;
} // PixelChecksum()

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...