Jump to content

Average colour of an area of the display


Melba23
 Share

Recommended Posts

  • Moderators

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

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

 

Link to comment
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
Link to comment
Share on other sites

  • Moderators

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

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

 

Link to comment
Share on other sites

  • Moderators

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

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

 

Link to comment
Share on other sites

  • 4 weeks later...

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
Link to comment
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

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
Link to comment
Share on other sites

  • Moderators

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

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

 

Link to comment
Share on other sites

  • Moderators

jeanjte,

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

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

 

Link to comment
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

Link to comment
Share on other sites

  • Moderators

jeantje,

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

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

 

Link to comment
Share on other sites

  • 3 years later...

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.

We ought not to misbehave, but we should look as though we could.

Link to comment
Share on other sites

  • Moderators

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

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

 

Link to comment
Share on other sites

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

Some guy's script + some other guy's script = my script!

Link to comment
Share on other sites

  • 2 years later...
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 Guest
Link to comment
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
 Share

  • Recently Browsing   0 members

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