Sign in to follow this  
Followers 0
yyywww

How to find a certain amount of color shades in a rectangle

9 posts in this topic

Hello,

I'm trying to write a small function that will return the amount of color shades of a provided color in a rectangular area.

PixelSearch returns only a single two-element array of the found pixel's coordinates.

I was wondering if there already is such a function or a user function that could do this job, and if not, how would I go about to write such a function? I was thinking of using PixelGetColor to go through the rectangle's coordinates, but PixelGetColor does not offer to return shades of a color if I'm not being mistaken.

For example, in the attached image, I would want the the function to return the amount of pixels that are either black or grey.

pixel.png

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

This example returns an array of all black and all grey/gray pixel colours/colors and their coordinates in the image from the opening post.

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <Array.au3>

; https://www.autoitscript.com/forum/topic/178404-how-to-find-a-certain-amount-of-color-shades-in-a-rectangle/?do=findComment&comment=1280204
Global $hGUI
Local $sImageIn = "GreyDots.png"
If FileExists($sImageIn) = 0 Then
    InetGet("https://www.autoitscript.com/forum/uploads/monthly_2015_10/pixel.png.d57bf025ea51e906e2fcb607dc86cce1.png", $sImageIn);
EndIf

DisplayImage($sImageIn)

$aArr = _PixelSearchArrayLock($sImageIn)
_ArrayDisplay($aArr, "_PixelSearchArrayLock", "", 0, "|", "Column|Row|Colour/Color", 500)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE


; Returns array of coordinates and colour/color of all black, and, grey/gray pixels.
; (Shades of grey/gray range from 0x010101, 0x020202, ... to ... , 0xFDFDFD, 0xFEFEFE.)
; Black is 0x000000, and, white is 0xFFFFFF ( in RGB (Red Green Blue) format, and, in 0xRRGGBB hexidecimal format).
Func _PixelSearchArrayLock($sImageIn)
    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile($sImageIn)
    $w = _GDIPlus_ImageGetWidth($hImage)
    $h = _GDIPlus_ImageGetHeight($hImage)
    ;ConsoleWrite($w & " x " & $h & " = " & ($w * $h / 2) & " = " & (($w - 1) * ($h - 1)) & @LF)
    Local $aArr[($w - 1) * ($h - 1) + 1][3]
    Local $Pix, $count = 0
    Local $aData[$h][$w]
    $BitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $w, $h, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    $Stride = DllStructGetData($BitmapData, "Stride")
    $Scan0 = DllStructGetData($BitmapData, "Scan0")
    For $row = 0 To $h - 1
        For $col = 0 To $w - 1
            $pixel = DllStructCreate("dword", $Scan0 + $row * $Stride + $col * 4)
            $Pix = Hex((DllStructGetData($pixel, 1)), 6)
            $Fst2 = StringLeft($Pix, 2)
            If ($Pix <> "FFFFFF") And $Fst2 = StringRight($Pix, 2) And $Fst2 = StringMid($Pix, 3, 2) Then
                $count += 1
                $aArr[$count][2] = "0x" & $Pix
                $aArr[$count][0] = $col
                $aArr[$count][1] = $row
            EndIf
            $aData[$row][$col] = "0x" & Hex((DllStructGetData($pixel, 1)), 6) ; All pixels
        Next
    Next
    _ArrayDisplay($aData, "Array of all pixel colours/colors")

    _GDIPlus_BitmapUnlockBits($hImage, $BitmapData)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    ReDim $aArr[$count + 1][3]
    $aArr[0][0] = $count
    Return $aArr
EndFunc   ;==>_PixelSearchArrayLock

; Display web image on a GUI.
Func DisplayImage($sImageIn)
    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile($sImageIn)
    $iIW = _GDIPlus_ImageGetWidth($hImage)
    $iIH = _GDIPlus_ImageGetHeight($hImage)

    $hGUI = GUICreate("Original", $iIW, $iIH)
    GUISetState()
    ; Draw original image
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hImage, 0, 0)
    ;__GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hImage, 0, 0, $iIW, $iIH, 0, 0, $iIW, $iIH)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
EndFunc   ;==>DisplayImage

 

Edited by Malkey

Share this post


Link to post
Share on other sites

What constitutes a shade of a pixel?

What is a shade of 0xFFFFFF?

@JohnOne
Using PixelSearch function
with the parameter color = 0xFFFFFF,
 and, a shade-variation = 1,
the colour/color and its shades  (or its colour-variations)  that can be matched are:-
0xFFFFFF,  0xFEFFFF,  0xFFFEFF,  0xFFFFFE,  0xFEFEFF, 0xFEFFFE, 0xFFFEFE, and 0xFEFEFE.

1 person likes this

Share this post


Link to post
Share on other sites

Thanks, is this information documented anywhere you know of?

From AutoIt Help file > PixelSearch function > the shade-variation parameter > Reads "[optional] A number between 0 and 255 to indicate the allowed number of shades of variation of the red, green, and blue components of the color. Default is 0 (exact match)."

And, experimenting with test examples like this one.

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>

If FileExists('ColorVariation.png') = 0 Then _ColorVariationPNGCreator()

; Open "ColorVariation.png" with Windows Photo Viewer
Run(@ComSpec & ' /c %SystemRoot%\System32\rundll32.exe "%ProgramFiles%\Windows Photo Viewer\PhotoViewer.dll", ImageView_Fullscreen ' & _
        @ScriptDir & '\ColorVariation.png', _
        @ScriptDir, @SW_HIDE, 2 + 4) ;
Opt("WinTitleMatchMode", -2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase
$hWin = WinWait('ColorVariation.png')

; Searching left to right, and top to bottom should find 0xD60000 first.
$aAr = PixelSearch(0, 0, 400, 300, 0xD70100, 0x01, 1, $hWin)
ConsoleWrite($aAr[0] & " x " & $aAr[1] & "  ")
ConsoleWrite(Hex(PixelGetColor($aAr[0], $aAr[1], $hWin), 6) & @LF)
MouseMove($aAr[0], $aAr[1])
Sleep(1000)

; Searching right to left, and bottom to top should find 0xD80000 first.
$aAr = PixelSearch(400, 300, 0, 0, 0xD70100, 1, 1, $hWin)
ConsoleWrite($aAr[0] & " x " & $aAr[1] & "  ")
ConsoleWrite(Hex(PixelGetColor($aAr[0], $aAr[1], $hWin), 6) & @LF)
MouseMove($aAr[0], $aAr[1])


Func _ColorVariationPNGCreator()
    Local $hGUI, $hGraphics, $hGraphic, $hBitmap, $hBrush, $hFormat, $hFamily, $hFont, $tLayout

    ; Create GUI
    $hGUI = GUICreate("GDI+", 400, 300)
    GUISetState()

    ; Draw a string
    _GDIPlus_Startup()
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    _GDIPlus_GraphicsClear($hGraphics, 0x00000000)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics(400, 300, $hGraphics)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    $hFormat = _GDIPlus_StringFormatCreate()
    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    $hFont = _GDIPlus_FontCreate($hFamily, 12, 1)

    For $h = 0 To 3
        For $i = 0 To 15
            $tLayout = _GDIPlus_RectFCreate(10 + ($h * 100), 10 + ($i * 15), 100, 15)
            $hBrush = _GDIPlus_BrushCreateSolid(Number("0xFF" & Hex(12 + $h, 1) & Hex($i, 1) & "0000"))
            _GDIPlus_GraphicsDrawStringEx($hGraphic, "0x" & Hex(12 + $h, 1) & Hex($i, 1) & "0000", $hFont, $tLayout, $hFormat, $hBrush)
        Next
    Next

    $tLayout = _GDIPlus_RectFCreate(60, 265, 300, 15)
    $hBrush = _GDIPlus_BrushCreateSolid(0xFF0000FF)
    _GDIPlus_GraphicsDrawStringEx($hGraphic, "Hex Colour Format: 0xRRGGBB", $hFont, $tLayout, $hFormat, $hBrush)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 400, 300)
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, 400, 300)
    _GDIPlus_ImageSaveToFile($hBitmap, "ColorVariation.png")


    ; Clean up resources
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()

EndFunc   ;==>_ColorVariationPNGCreator

 

From here.

is a handy tooltip utility that shows the current client coordinates with the current pixel colour.   Best used when compiled, to avoid conflict with running scripts from SciTE.

And from here,

I use Siao's magnifier and info tool complied. You'll need to comment out, or delete, about six Global Const declarations in the script because those Global Const have been added to the include file.   Using Siao's magnifier, the random pixel colours at the border of all the text is visible.

1 person likes this

Share this post


Link to post
Share on other sites

@ Malkey

Thank you! This is very helpful to me and I think I can learn a lot from your script.

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
Sign in to follow this  
Followers 0