Melba23

Average colour of an area of the display

35 posts in this topic

#1 ·  Posted (edited)

New version: Uploaded on 20 Jan 10

I wrote this in response to a forum question and thought it might be useful more widely as I have seen a few posts about average colour values before.

The function returns the average colour value (in hex RGB format) over a selected area of the display. The user can define the area and also the resolution of the averaging. Obviously the resolution determines the accuracy of the result and the speed of the operation. As an example, I got the following values from my 1680x1050 display running at 2.13 GHz on Vista Home Premium. The display was about 50% SciTE and 50% blue desktop:

Step     Time         Av Colour

100      60ms         8899C2
10       720ms        92A6C7
5        2.7 secs     91A4C6
2        16.5 secs    92A6C7
1        65.7 secs    92A6C7

In testing I found that using a resolution of 10 gave an excellent average colour value at a reasonable speed - so I chose that as the default value.

Edit: As requested by picea892 below, the function will now accept a HANDLE for a GUI or a control and automatically set its client area as the area to average.

Edit 2: Fixed a memory leak - see below for details.

Edit 3: Fixed code for new Hex behaviour - see below for details.

The function itself, including a short example:

New version in post #10 below

As always, comments welcome - and criticism, as I am not a GDI expert by any means. ;)

M23

Edited by Melba23
Removed code

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites



Hi Melba23

I know when you post an example it's going to be a good one. Someone as active on the forums as you who rarely posts in the examples, certainly will be a quality script and of course I am not disappointed. I really like this function, thanks for sharing. Would you take a tweak request? I certainly can get the rect of a window and guictrl and pass it to the function but was wondering if you would consider building it in. I'm thinking, you pass the window handle or guicontrol and it calculates the rect inside the function. When I have time I will look into doing it too.

Again, thankyou.

Picea892

Another example to simply show the colour

$iAverage_Colour = _Area_Average_Colour()
GUICreate("",200,200,-1,-1)
GUICtrlCreateGraphic(0,0,200,200)
GUICtrlSetBkColor(-1, "0x"&$iAverage_Colour)
GUISetState()
while 1
sleep(100)
wend

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

picea892,

As my better half is glued to "Strictly Come Dancing", I have been able to rustle this up fairly quickly:

New version in post #10 below

Note you must pass the HANDLE of a control, not its internal AutoIt ControlID. And as a bonus, WinAPI.au3 is already included by GDIPlus.au3. ;)

Will that do? :evil:

M23

Edited by Melba23
Removed code

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

Should work for most people...hey if I didn't suggest it...it would have come up .

I'm glad you were willing to take it on, you approached it in a much better way than I would have. Thanks for humouring me.

Picea

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

You can make it shorter by the average code. :evil::idea:

Add all divide by how many you added eg. :evil:

1

3

1+3/2

4/2

2.................:)

2 is average ;)

Edited by CalvinAndHobbesRules

Hi.

Share this post


Link to post
Share on other sites

CalvinAndHobbesRules,

Thank you for this lesson in basic maths. I particularly liked the choice of emoticons, very tasteful. :evil:

Perhaps you might like to consider what happens when you average a very large area with a small step distance. If you just keep adding the pixel values you get a very large number to divide. Were you aware that AutoIt has a maximum limit for numbers? Probably not, so here is the quote from the Help file:

Number range (integers): 64-bit signed integer

Hexadecimal numbers: 32-bit signed integer (0x80000000 to 0x7FFFFFFF)

I therefore decided to take interim averages to prevent the total getting anywhere near this limit on very large displays with the minimum step distance. But you seem to have missed the line in the script explaining that - for your information it reads:

; Determine average value so far - this prevents value becoming too large

This sort of "thinking ahead" makes the code useable by others whose machines might not have the same specification as the author. You might notice one or two other areas of the script where some "errorchecking" has been done so that other users get a suitable error message to help them determine what might have gone wrong.

So, may I suggest you press your "Neck Retract" button firmly and think twice before posting such ill-informed and frankly insulting comments again.

Do have a nice day! ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

I know this is old but i have a problem the problem is when i call this each second it will suck up all my memory

System:

OS: Windows 7 32-Bit

CPU: Intel Pentium 4 3.06 GHz

Ram: 2GB DDR2 667 MHz


Share this post


Link to post
Share on other sites

Sucks up quiet some cpu power, but I can't see a memory leak...

#include <GDIPlus.au3>
#include <Color.au3>
#include <ScreenCapture.au3>

$hGUI = GUICreate("test", 500, 500)
$hIcon = GUICtrlCreateIcon(@AutoItExe, -1, 0, 0, 100, 100)
GUICtrlCreateLabel("", 200, 200, 200, 200)
GUICtrlSetBkColor(-1, 0xFF0000)
GUISetState()

Sleep(1000)

GUICtrlCreateLabel("", 0, 190, 500, 280)
GUICtrlSetBkColor(-1, 0)

$cScreen_Average = GUICtrlCreateLabel("Screen Average Colour", 10, 200, 480, 50)

While 1

    $sScreen_Average = _Area_Average_Colour()
    GUICtrlSetBkColor($cScreen_Average, Dec($sScreen_Average))
    Sleep(1000)
    If GUIGetMsg() = -3 Then Exit
WEnd

; End of example
; ============================

; #FUNCTION# =========================================================================================================
; Name...........: _Area_Average_Colour
; Description ...: Returns average colour within a defined are of the display
; Syntax ........: _Area_Average_Colour([$iStep [, $iLeft [, $iTop [, $iWidth [, $iHeight ]]]]])
; Parameters ....: $iStep   - Pixel resolution value.  Lower values give better resolution but take longer. (Default = 10)
;                  $iLeft   - X coordinate of top-left corner of area (Default = 0 - left edge of screen)
;                           - If this parameter holds a window HANDLE, the area is set to the client area of the window
;                  $iTop    - Y coordinate of top-left corner of area (Default = 0 - top edge of screen)
;                  $iWidth  - Width of the area (Default = @DesktopWidth)
;                  $iHeight - Height of the area (Default = @DesktopHeight)
; Requirement(s) : v3.3.0.0 or higher
; Return values .: Success - Returns six character string containing RGB hex values
;                  Failure - Returns 0 and sets @error:
;                  1 - Screen Capture failure
;                  2 - GDI function failure
; Author ........: Melba23.   Credit to Malkey for the basic GDI code
; Modified ......:
; Remarks .......:
; Example .......: Yes
;=====================================================================================================================
Func _Area_Average_Colour($iStep = 10, $iLeft = 0, $iTop = 0, $iWidth = @DesktopWidth, $iHeight = @DesktopHeight)

    Local $iBlue = 0, $iGreen = 0, $iRed = 0, $iInterim_Blue = 0, $iInterim_Green = 0, $iInterim_Red = 0, $iInner_Count = 0, $iOuter_Count = 0

    If IsHWnd($iLeft) Then
        Local $hWnd = $iLeft
        Local $tPoint = DllStructCreate("int X;int Y")
        DllStructSetData($tPoint, "X", 0)
        DllStructSetData($tPoint, "Y", 0)
        _WinAPI_ClientToScreen($hWnd, $tPoint)
        $iLeft = DllStructGetData($tPoint, "X")
        $iTop = DllStructGetData($tPoint, "Y")
        Local $aSize = WinGetClientSize($hWnd)
        $iWidth = $aSize[0]
        $iHeight = $aSize[1]
    EndIf

    _GDIPlus_Startup()

    Local $hBMP = _ScreenCapture_Capture("", $iLeft, $iTop, $iLeft + $iWidth, $iTop + $iHeight)
    If $hBMP = 0 Then
        _GDIPlus_Shutdown()
        Return SetError(1, 0, 0)
    EndIf

    Local $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
    If $hImage = 0 Then
        _GDIPlus_Shutdown()
        Return SetError(2, 0, 0)
    EndIf

    Local $tRes = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iWidth, $iHeight, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)
    If @error Then
        _GDIPlus_GraphicsDispose($hImage)
        _GDIPlus_Shutdown()
        Return SetError(2, 0, 0)
    EndIf

    ;Get the returned values of _GDIPlus_BitmapLockBits()
    Local $iLock_Width = DllStructGetData($tRes, "width")
    Local $iLock_Height = DllStructGetData($tRes, "height")
    Local $iLock_Stride = DllStructGetData($tRes, "stride")
    Local $iLock_Scan0 = DllStructGetData($tRes, "Scan0")

    ; Run through the BitMap testing pixels at the step distance
    For $i = 0 To $iWidth - 1 Step $iStep
        For $j = 0 To $iHeight - 1 Step $iStep
            Local $v_Buffer = DllStructCreate("dword", $iLock_Scan0 + ($j * $iLock_Stride) + ($i * 4))
            ; Get colour value of pixel
            Local $v_Value = DllStructGetData($v_Buffer, 1)
            ; Add components
            $iBlue += _ColorGetBlue($v_Value)
            $iGreen += _ColorGetGreen($v_Value)
            $iRed += _ColorGetRed($v_Value)
            ; Adjust counter
            $iInner_Count += 1
        Next
        ; Determine average value so far - this prevents value becoming too large
        $iInterim_Blue += $iBlue / $iInner_Count
        $iBlue = 0
        $iInterim_Green += $iGreen / $iInner_Count
        $iGreen = 0
        $iInterim_Red += $iRed / $iInner_Count
        $iRed = 0
        ; Adjust counters
        $iInner_Count = 0
        $iOuter_Count += 1
    Next
    ; Determine final average
    Local $avBlue = Hex(Round($iInterim_Blue / $iOuter_Count, 0), 2)
    Local $avGreen = Hex(Round($iInterim_Green / $iOuter_Count, 0), 2)
    Local $avRed = Hex(Round($iInterim_Red / $iOuter_Count, 0), 2)

    ; Clear up
    _GDIPlus_BitmapUnlockBits($hImage, $tRes)
    _GDIPlus_GraphicsDispose($hImage)
    _GDIPlus_Shutdown()

    Return ($avRed & $avGreen & $avBlue)

EndFunc   ;==>_Area_Average_Colour

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Sucks up quiet some cpu power, but I can't see a memory leak...

#include <GDIPlus.au3>
#include <Color.au3>
#include <ScreenCapture.au3>

$hGUI = GUICreate("test", 500, 500)
$hIcon = GUICtrlCreateIcon(@AutoItExe, -1, 0, 0, 100, 100)
GUICtrlCreateLabel("", 200, 200, 200, 200)
GUICtrlSetBkColor(-1, 0xFF0000)
GUISetState()

Sleep(1000)

GUICtrlCreateLabel("", 0, 190, 500, 280)
GUICtrlSetBkColor(-1, 0)

$cScreen_Average = GUICtrlCreateLabel("Screen Average Colour", 10, 200, 480, 50)

While 1

    $sScreen_Average = _Area_Average_Colour()
    GUICtrlSetBkColor($cScreen_Average, Dec($sScreen_Average))
    Sleep(1000)
    If GUIGetMsg() = -3 Then Exit
WEnd

; End of example
; ============================

; #FUNCTION# =========================================================================================================
; Name...........: _Area_Average_Colour
; Description ...: Returns average colour within a defined are of the display
; Syntax ........: _Area_Average_Colour([$iStep [, $iLeft [, $iTop [, $iWidth [, $iHeight ]]]]])
; Parameters ....: $iStep   - Pixel resolution value.  Lower values give better resolution but take longer. (Default = 10)
;                  $iLeft   - X coordinate of top-left corner of area (Default = 0 - left edge of screen)
;                           - If this parameter holds a window HANDLE, the area is set to the client area of the window
;                  $iTop    - Y coordinate of top-left corner of area (Default = 0 - top edge of screen)
;                  $iWidth  - Width of the area (Default = @DesktopWidth)
;                  $iHeight - Height of the area (Default = @DesktopHeight)
; Requirement(s) : v3.3.0.0 or higher
; Return values .: Success - Returns six character string containing RGB hex values
;                  Failure - Returns 0 and sets @error:
;                  1 - Screen Capture failure
;                  2 - GDI function failure
; Author ........: Melba23.   Credit to Malkey for the basic GDI code
; Modified ......:
; Remarks .......:
; Example .......: Yes
;=====================================================================================================================
Func _Area_Average_Colour($iStep = 10, $iLeft = 0, $iTop = 0, $iWidth = @DesktopWidth, $iHeight = @DesktopHeight)

    Local $iBlue = 0, $iGreen = 0, $iRed = 0, $iInterim_Blue = 0, $iInterim_Green = 0, $iInterim_Red = 0, $iInner_Count = 0, $iOuter_Count = 0

    If IsHWnd($iLeft) Then
        Local $hWnd = $iLeft
        Local $tPoint = DllStructCreate("int X;int Y")
        DllStructSetData($tPoint, "X", 0)
        DllStructSetData($tPoint, "Y", 0)
        _WinAPI_ClientToScreen($hWnd, $tPoint)
        $iLeft = DllStructGetData($tPoint, "X")
        $iTop = DllStructGetData($tPoint, "Y")
        Local $aSize = WinGetClientSize($hWnd)
        $iWidth = $aSize[0]
        $iHeight = $aSize[1]
    EndIf

    _GDIPlus_Startup()

    Local $hBMP = _ScreenCapture_Capture("", $iLeft, $iTop, $iLeft + $iWidth, $iTop + $iHeight)
    If $hBMP = 0 Then
        _GDIPlus_Shutdown()
        Return SetError(1, 0, 0)
    EndIf

    Local $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
    If $hImage = 0 Then
        _GDIPlus_Shutdown()
        Return SetError(2, 0, 0)
    EndIf

    Local $tRes = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iWidth, $iHeight, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)
    If @error Then
        _GDIPlus_GraphicsDispose($hImage)
        _GDIPlus_Shutdown()
        Return SetError(2, 0, 0)
    EndIf

    ;Get the returned values of _GDIPlus_BitmapLockBits()
    Local $iLock_Width = DllStructGetData($tRes, "width")
    Local $iLock_Height = DllStructGetData($tRes, "height")
    Local $iLock_Stride = DllStructGetData($tRes, "stride")
    Local $iLock_Scan0 = DllStructGetData($tRes, "Scan0")

    ; Run through the BitMap testing pixels at the step distance
    For $i = 0 To $iWidth - 1 Step $iStep
        For $j = 0 To $iHeight - 1 Step $iStep
            Local $v_Buffer = DllStructCreate("dword", $iLock_Scan0 + ($j * $iLock_Stride) + ($i * 4))
            ; Get colour value of pixel
            Local $v_Value = DllStructGetData($v_Buffer, 1)
            ; Add components
            $iBlue += _ColorGetBlue($v_Value)
            $iGreen += _ColorGetGreen($v_Value)
            $iRed += _ColorGetRed($v_Value)
            ; Adjust counter
            $iInner_Count += 1
        Next
        ; Determine average value so far - this prevents value becoming too large
        $iInterim_Blue += $iBlue / $iInner_Count
        $iBlue = 0
        $iInterim_Green += $iGreen / $iInner_Count
        $iGreen = 0
        $iInterim_Red += $iRed / $iInner_Count
        $iRed = 0
        ; Adjust counters
        $iInner_Count = 0
        $iOuter_Count += 1
    Next
    ; Determine final average
    Local $avBlue = Hex(Round($iInterim_Blue / $iOuter_Count, 0), 2)
    Local $avGreen = Hex(Round($iInterim_Green / $iOuter_Count, 0), 2)
    Local $avRed = Hex(Round($iInterim_Red / $iOuter_Count, 0), 2)

    ; Clear up
    _GDIPlus_BitmapUnlockBits($hImage, $tRes)
    _GDIPlus_GraphicsDispose($hImage)
    _GDIPlus_Shutdown()

    Return ($avRed & $avGreen & $avBlue)

EndFunc   ;==>_Area_Average_Colour

I am experiencing the memory issue as well. Running the script causes the mem usage to grow and grow until POOF!

Seems to only happen when using the Non-Beta.....even with Melbas mods below.

Edited by spudw2k

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Hi all,

I have located 2 leaks - used the wrong command to release the BitmapCreateFromHBITMAP image; completely forgot to release the _ScreenCapture_Capture bitmap. :D

I have had this new version running on test this evening and it seems completely stable:

Cycles    Mem used in Task Manager
100       18940
200       18940
300       18940
400       18940
500       18940
600       18940
700       18940  
800       18940
900       18940
1000      18940

The new version (changes = <<<<<<<<<<):

; #FUNCTION# =========================================================================================================
; Name...........: _Area_Average_Colour
; Description ...: Returns average colour within a defined are of the display
; Syntax ........: _Area_Average_Colour([$iStep [, $iLeft [, $iTop [, $iWidth [, $iHeight ]]]]])
; Parameters ....: $iStep   - Pixel resolution value.  Lower values give better resolution but take longer. (Default = 10)
;                  $iLeft   - X coordinate of top-left corner of area (Default = 0 - left edge of screen)
;                           - If this parameter holds a window HANDLE, the area is set to the client area of the window
;                  $iTop    - Y coordinate of top-left corner of area (Default = 0 - top edge of screen)
;                  $iWidth  - Width of the area (Default = @DesktopWidth)
;                  $iHeight - Height of the area (Default = @DesktopHeight)
; Requirement(s) : v3.3.0.0 or higher
; Return values .: Success - Returns six character string containing RGB hex values
;                  Failure - Returns 0 and sets @error:
;                  1 - Screen Capture failure
;                  2 - GDI function failure
; Author ........: Melba23.   Credit to Malkey for the basic GDI code
; Modified ......:
; Remarks .......:
; Example .......: Yes
;=====================================================================================================================
Func _Area_Average_Colour($iStep = 10, $iLeft = 0, $iTop = 0, $iWidth = @DesktopWidth, $iHeight = @DesktopHeight)

    Local $iBlue = 0, $iGreen = 0, $iRed = 0, $iInterim_Blue = 0, $iInterim_Green = 0, $iInterim_Red = 0, $iInner_Count = 0, $iOuter_Count = 0

    If IsHWnd($iLeft) Then
        $hWnd = $iLeft
        Local $tPoint = DllStructCreate("int X;int Y")
        DllStructSetData($tpoint, "X", 0)
        DllStructSetData($tpoint, "Y", 0)
        _WinAPI_ClientToScreen($hWnd, $tPoint)
        $iLeft = DllStructGetData($tPoint, "X")
        $iTop = DllStructGetData($tPoint, "Y")
        $aSize = WinGetClientSize($hWnd)
        $iWidth =  $aSize[0]
        $iHeight = $aSize[1]
    EndIf

    _GDIPlus_Startup()

    Local $hBMP = _ScreenCapture_Capture("", $iLeft, $iTop, $iLeft + $iWidth, $iTop + $iHeight)
    If $hBMP = 0 Then
        _GDIPlus_Shutdown()
        Return SetError(1, 0, 0)
    EndIf

    Local $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
    If $hImage = 0 Then
        _WinAPI_DeleteObject($hBMP) ; <<<<<<<<<<<<<
        _GDIPlus_Shutdown()
        Return SetError(2, 0, 0)
    EndIf

    Local $tRes = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iWidth, $iHeight, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)
    If @error Then
        _GDIPlus_BitmapDispose($hImage) ; <<<<<<<<<<<<<
        _WinAPI_DeleteObject($hBMP)     ; <<<<<<<<<<<<<
        _GDIPlus_Shutdown()
        Return SetError(2, 0, 0)
    EndIf

    ;Get the returned values of _GDIPlus_BitmapLockBits()
    Local $iLock_Width  = DllStructGetData($tRes, "width")
    Local $iLock_Height = DllStructGetData($tRes, "height")
    Local $iLock_Stride = DllStructGetData($tRes, "stride")
    Local $iLock_Scan0  = DllStructGetData($tRes, "Scan0")

    ; Run through the BitMap testing pixels at the step distance
    For $i = 0 To $iWidth - 1 Step $iStep
        For $j = 0 To $iHeight - 1 Step $iStep
            Local $v_Buffer = DllStructCreate("dword", $iLock_Scan0 + ($j * $iLock_Stride) + ($i * 4))
            ; Get colour value of pixel
            Local $v_Value = DllStructGetData($v_Buffer, 1)
            ; Add components
            $iBlue  += _ColorGetBlue($v_Value)
            $iGreen += _ColorGetGreen($v_Value)
            $iRed   += _ColorGetRed($v_Value)
            ; Adjust counter
            $iInner_Count += 1
        Next
        ; Determine average value so far - this prevents value becoming too large
        $iInterim_Blue  += $iBlue / $iInner_Count
        $iBlue = 0
        $iInterim_Green += $iGreen / $iInner_Count
        $iGreen = 0
        $iInterim_Red   += $iRed / $iInner_Count
        $iRed = 0
        ; Adjust counters
        $iInner_Count = 0
        $iOuter_Count += 1
    Next
    ; Determine final average
    Local $avBlue = Hex(Int(Round($iInterim_Blue / $iOuter_Count, 0)), 2)
    Local $avGreen = Hex(Int(Round($iInterim_Green / $iOuter_Count, 0)), 2)
    Local $avRed = Hex(Int(Round($iInterim_Red / $iOuter_Count, 0)), 2)

    ; Clear up

    _GDIPlus_BitmapUnlockBits($hImage, $tRes)
    _GDIPlus_BitmapDispose($hImage) ; <<<<<<<<<<<<<
    _WinAPI_DeleteObject($hBMP)     ; <<<<<<<<<<<<<
    _GDIPlus_Shutdown()

    Return ($avRed & $avGreen & $avBlue)

EndFunc   ;==>_Area_Average_Colour

Sorry about that - told you in the first post I was not an expert at GDI! :huggles:

M23

Edited by Melba23
Amended code - see post #17 below

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

No problem Melba23, but thanks for fixing it

Best Regards Jeantje


Share this post


Link to post
Share on other sites

jeanjte,

Can you confirm that you have no more memory leakage problem with this new version?

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

jeanjte,

Can you confirm that you have no more memory leakage problem with this new version?

M23

I can confirm that I have no mem leaks anymore, but I still can't use this function in my application

It's still to slow, but great work Melba23


Share this post


Link to post
Share on other sites

jeantje,

Thanks for that. Sorry I cannot make it any faster in return! :D

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

very cool Melba :huggles:

GJ :D

Share this post


Link to post
Share on other sites

Hey Melba. This looks pretty cool, and is actually something that I need for a project that I'm working on, but I can't get it to return anything but 000000. Even with your example, all the console writes are 000000. Just calling the function (so it scans my whole screen) returns 000000...

Any ideas why? Broken in an update to AutoIt? Something probably wrong with my display drivers that just return the ScreenCapture as black? I'm running the newest AutoIt version.


RAWR! I'm hungry :( Feed the panda squirrle

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

mistersquirrle,

Broken in an update to AutoIt?

Indeed it was - I wonder how many scripts have failed because of the little-understood change in behaviour of the Hex function? We were only discussing it recently, so it seemed a sensible place to start looking! :D

Just replace these lines at the end of the function and all will work correctly. ;)

; Determine final average
Local $avBlue = Hex(Int(Round($iInterim_Blue / $iOuter_Count, 0)), 2)
Local $avGreen = Hex(Int(Round($iInterim_Green / $iOuter_Count, 0)), 2)
Local $avRed = Hex(Int(Round($iInterim_Red / $iOuter_Count, 0)), 2)

Thanks for pointing out the problem - I have amended the example in post #10 above. :)

M23

Edited by Melba23
Added link

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

Thank you Melba :) does indeed work correctly (at least I'm not getting 000000 :P getting actual values now).

Now I just have to hope that I can use the values correctly for what I'm doing (and that it'll actually help).


RAWR! I'm hungry :( Feed the panda squirrle

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

Resizing an image to 1x1 pixels gives you the average color of the original image. :)

May be a bit faster, dunno, havent tested, UEZ got some resizing scripts floating around if you wanna test it.

Edited by Werty

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

On 19.3.2013 at 2:39 PM, Werty said:

Resizing an image to 1x1 pixels gives you the average color of the original image. :)

 

May be a bit faster, dunno, havent tested, UEZ got some resizing scripts floating around if you wanna test it.

Done

#include <GUIConstantsEx.au3>
#include <ScreenCapture.au3>

_GDIPlus_Startup()

$hex_avColor = Screen_Area_Average_Color(10,10,400,400)
ConsoleWrite($hex_avColor& @CRLF)

Func Screen_Area_Average_Color($x_pos,$y_pos,$x_size,$y_size,$bRetunAsHex = 1)
    Local $Output = -1, _
    $hHBmp = _ScreenCapture_Capture("", $x_pos, $y_pos, $x_size, $y_size) ;create a GDI bitmap by capturing full screen of the desktop
    If @error Then Return SetError(1)
    Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) ;convert GDI bitmap to GDI+ bitmap
    If Not @error Then
        Local $hBitmap_Scaled = _GDIPlus_ImageResize($hBitmap, 1, 1) ;resize image to 1x1
        If Not @error Then
            $Output = _GDIPlus_BitmapGetPixel($hBitmap_Scaled,0,0) ; Get color of the 1x1 pixel
            If Not @error Then
                If $bRetunAsHex Then $Output = Hex($Output,6)
            EndIf
            _GDIPlus_BitmapDispose($hBitmap_Scaled) ; release $hBitmap_Scaled
        EndIf

         _GDIPlus_BitmapDispose($hBitmap) ; release $hBitmap
    EndIf
    _WinAPI_DeleteObject($hHBmp) ;release GDI bitmap resource because not needed anymore
    If $Output = -1 Then Return SetError(1)
    Return $Output
EndFunc

It works fast.
Thanks for the idea

EDIT:

I did a mistake in this code. Try the code in the next page, post 23.

Edited by gil900

Share this post


Link to post
Share on other sites

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