Jump to content

Recommended Posts

Posted (edited)

Hi forum!

I work in algorithm to cut any king of image in a PNG transparent.

The form does not matter, if it have a form, the basic principle is: one pixel is neighbor of another pixel.

If have transparece between pixels, it is not neighbor.

After many hours I found a pseudo-code: Moore neighborhood.

Have another interesting page: https://en.wikipedia.org/wiki/Connected-component_labeling

But, I read and can't translate the pseudo code to AutoIt.

I want only cut any kind of image (regular ou irregular) rounded/bordered with transparency in PNG image.

Question, someone have development some code to do this in AutoIt?

"Moore neighborhood" is the correct pseudo-code to solve this?

Regards, Luigi

 

Code updated.

;~ https://en.wikipedia.org/wiki/Connected-component_labeling
;~ #AutoIt3Wrapper_AU3Check_Parameters= -q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7
;~ #Tidy_Parameters=/sf

#include-once
#include <WinAPI.au3>
#include <Array.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>

#include <object_dump.au3>

OnAutoItExitRegister("_on_exit")

Opt("GUIOnEventMode", 1)
Opt("GUIEventOptions", 1)
Opt("MustDeclareVars", 1)

Global Const $SEP = "#"
Global $aGuiSize[2] = [800, 600]
Global $sGuiTitle = "GuiTitle"
Global $hGui
Global $ax[2], $ay[2]
Global $iSize = 32
Global $ALL[1][5] = [[0]]
Global $iChield, $aPos

Global $POS, $iNext, $iSearch, $color

; grid or image
; 0 is transparency
; non-zero (value does not matter) is any color
Global $aGrid[][12] = [ _
        [0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0], _
        [0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1], _
        [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0], _
        [0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0], _
        [1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0], _
        [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], _
        [0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1], _
        [0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1], _
        [0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0], _
        [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0] _
        ]

; array to analise
Global $aMax[4] = [UBound($aGrid, 1), UBound($aGrid, 2)]
$aMax[2] = $aMax[0] - 1
$aMax[3] = $aMax[1] - 1

Global $hArr[$aMax[0]][$aMax[1]]

$hGui = GUICreate($sGuiTitle, $aGuiSize[0], $aGuiSize[1])
GUISetOnEvent($GUI_EVENT_CLOSE, "_quit")
GUISetState(@SW_SHOW, $hGui)

For $LIN = 0 To $aMax[2]
    For $COL = 0 To $aMax[3]
        $hArr[$LIN][$COL] = GUICtrlCreateLabel($aGrid[$LIN][$COL], $iSize + $COL * $iSize, $iSize + $LIN * $iSize, $iSize, $iSize, BitOR($SS_SUNKEN, $SS_CENTER))
        $color = Color()
        GUICtrlSetBkColor($hArr[$LIN][$COL], $aGrid[$LIN][$COL] ? $color : 0xFFFFCC)
        GUICtrlSetTip($hArr[$LIN][$COL], $LIN & "," & $COL)
        If $aGrid[$LIN][$COL] Then Populate($ALL, $LIN, $COL, $LIN & $SEP & $COL, $color)
    Next
Next

Colorate()
;~ _ArrayDisplay($ALL, "Neighbors pixels", 0, 0, Default, "$LIN|$COL|$POS|$COLOR|$parent")

Func Populate(ByRef $aInput, $LIN, $COL, $POS, $color, $parent = 0)
    $iSearch = _ArraySearch($ALL, $POS, 1, Default, 0, 0, 2, 2)
    Local $viz
    If Not @error Then Return
    $LIN = Number($LIN)
    $COL = Number($COL)
    If $parent Then
        Local $iRedim = UBound($aInput, 1)
        ReDim $aInput[$iRedim + 1][5]
        $aInput[0][0] = $iRedim
        $aInput[$iRedim][0] = $LIN
        $aInput[$iRedim][1] = $COL
        $aInput[$iRedim][2] = $POS
        $aInput[$iRedim][3] = $color
        $aInput[$iRedim][4] = $parent

        $viz = __GetNeighbor($aGrid, $LIN, $COL)
        For $ii = 1 To $viz[0]
            $aPos = StringSplit($viz[$ii], $SEP, 2)
            Populate($ALL, $aPos[0], $aPos[1], $viz[$ii], $color, $parent)
        Next
    Else
        Local $iRedim = UBound($aInput, 1)
        ReDim $aInput[$iRedim + 1][5]
        $aInput[0][0] = $iRedim
        $aInput[$iRedim][0] = $LIN
        $aInput[$iRedim][1] = $COL
        $aInput[$iRedim][2] = $POS
        $aInput[$iRedim][3] = $color
        $aInput[$iRedim][4] = $iRedim

        $viz = __GetNeighbor($aGrid, $LIN, $COL)
        If $viz[0] >= 1 Then
            For $ii = 1 To $viz[0]
                $aPos = StringSplit($viz[$ii], $SEP, 2)
                Populate($ALL, $aPos[0], $aPos[1], $viz[$ii], $color, $iRedim)
            Next
        EndIf
    EndIf
    Return $iRedim
EndFunc   ;==>Populate

Func Colorate()
    For $ii = 1 To $ALL[0][0]
        If Not ($ii = $ALL[$ii][4]) Then
            GUICtrlSetBkColor($hArr[$ALL[$ii][0]][$ALL[$ii][1]], $ALL[$ii][3])
        EndIf
    Next
EndFunc   ;==>Colorate


While Sleep(25)
WEnd

Func _on_exit()
    GUISetState($hGui, @SW_HIDE)
    GUIDelete($hGui)
EndFunc   ;==>_on_exit

Func _quit()
    Exit
EndFunc   ;==>_quit

Func __GetNeighbor($aInput, $LIN, $COL)
    Local $aRet[1] = [0]

    $ax[0] = $LIN - 1
    $ax[0] = $ax[0] < 0 ? 0 : $ax[0]

    $ax[1] = $LIN + 1
    $ax[1] = $ax[1] > UBound($aInput, 1) - 1 ? UBound($aInput, 1) - 1 : $ax[1]

    $ay[0] = $COL - 1
    $ay[0] = $ay[0] < 0 ? 0 : $ay[0]

    $ay[1] = $COL + 1
    $ay[1] = $ay[1] > UBound($aInput, 2) - 1 ? UBound($aInput, 2) - 1 : $ay[1]

    For $yy = $ax[0] To $ax[1]
        For $xx = $ay[0] To $ay[1]
            If $aInput[$yy][$xx] And Not ($yy = $LIN And $xx = $COL) Then _ArrayAdd($aRet, $yy & $SEP & $xx)
        Next
    Next
    If UBound($aRet, 1) - 1 > 0 Then $aRet[0] = UBound($aRet, 1) - 1
;~  If $LIN = 3 And $COL = 7 Then _ArrayDisplay($aRet)
    Return $aRet
EndFunc   ;==>__GetNeighbor

Func Color()
    Return "0x" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2)
EndFunc   ;==>Color

 

New interactive example.

Click with right buton over labes to (enable/disable) and click on button "Neighbors" to run algorithm.

;~ https://en.wikipedia.org/wiki/Connected-component_labeling
;~ #AutoIt3Wrapper_AU3Check_Parameters= -q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7
;~ #Tidy_Parameters=/sf


#include-once
#include <WinAPI.au3>
#include <Array.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPIGdi.au3>

#include <object_dump.au3>

OnAutoItExitRegister("_on_exit")

Opt("GUIOnEventMode", 1)
Opt("GUIEventOptions", 1)
Opt("MustDeclareVars", 1)

Global Const $SEP = "#"
Global $aGuiSize[2] = [800, 600]
Global $sGuiTitle = "GuiTitle"
Global $hGui
Global $ax[2], $ay[2]
Global $iSize = 32
Global $ALL[1][5] = [[0]]
Global $iChield, $aPos
Global Const $SD = "Scripting.Dictionary"
Global $oIndex = ObjCreate($SD)
Global $aMouse, $aClick[2]
Global $ON = 0xABA69E, $OFF = 0xD4D0C8
Global $hNeighbors

Global $POS, $iNext, $iSearch, $color

; grid or image
; 0 is transparency
; non-zero (value does not matter) is any color
Global $aGrid[][12] = [ _
        [0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0], _
        [0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1], _
        [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0], _
        [0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0], _
        [1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0], _
        [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], _
        [0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1], _
        [0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1], _
        [0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0], _
        [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0] _
        ]

; array to analise
Global $aMax[4] = [UBound($aGrid, 1), UBound($aGrid, 2)]
$aMax[2] = $aMax[0] - 1
$aMax[3] = $aMax[1] - 1

Global $hArr[$aMax[0]][$aMax[1]]

$hGui = GUICreate($sGuiTitle, $aGuiSize[0], $aGuiSize[1])
GUISetOnEvent($GUI_EVENT_CLOSE, "_quit")
GUISetState(@SW_SHOW, $hGui)
$hNeighbors = GUICtrlCreateButton("Neighbors", $iSize, 10, 80, 20)
GUICtrlSetOnEvent($hNeighbors, "Neighbors")

For $LIN = 0 To $aMax[2]
    For $COL = 0 To $aMax[3]
        $hArr[$LIN][$COL] = GUICtrlCreateLabel($aGrid[$LIN][$COL], $iSize + $COL * $iSize, $iSize + $LIN * $iSize, $iSize, $iSize, BitOR($SS_SUNKEN, $SS_CENTER))
        $color = Color()
        GUICtrlSetBkColor($hArr[$LIN][$COL], $aGrid[$LIN][$COL] ? $color : $OFF)
        GUICtrlSetTip($hArr[$LIN][$COL], $LIN & "," & $COL)
        If $aGrid[$LIN][$COL] Then Populate($ALL, $LIN, $COL, $LIN & $SEP & $COL, $color)
        __index($oIndex, $hArr[$LIN][$COL], $LIN, $COL)
    Next
Next

Func __index(ByRef $oo, $handle, $LIN = 0, $COL = 0)
    Local $arr[2] = [$LIN, $COL]
    $oo.Add($handle, $arr)
EndFunc   ;==>__index

Func Neighbors()
    Global $ALL[1][5] = [[0]]
    For $LIN = 0 To $aMax[2]
        For $COL = 0 To $aMax[3]
            $color = Color()
            GUICtrlSetBkColor($hArr[$LIN][$COL], $aGrid[$LIN][$COL] ? $color : $OFF)
            If $aGrid[$LIN][$COL] Then Populate($ALL, $LIN, $COL, $LIN & $SEP & $COL, $color)
        Next
    Next
    Colorate()
EndFunc   ;==>Neighbors

Colorate()
;~ _ArrayDisplay($ALL, "Neighbors pixels", 0, 0, Default, "$LIN|$COL|$POS|$COLOR|$parent")

Func Populate(ByRef $aInput, $LIN, $COL, $POS, $color, $parent = 0)
    $iSearch = _ArraySearch($ALL, $POS, 1, Default, 0, 0, 2, 2)
    If Not @error Then Return
    Local $viz
    $LIN = Number($LIN)
    $COL = Number($COL)
    If $parent Then
        Local $iRedim = UBound($aInput, 1)
        ReDim $aInput[$iRedim + 1][5]
        $aInput[0][0] = $iRedim
        $aInput[$iRedim][0] = $LIN
        $aInput[$iRedim][1] = $COL
        $aInput[$iRedim][2] = $POS
        $aInput[$iRedim][3] = $color
        $aInput[$iRedim][4] = $parent

        $viz = __GetNeighbor($aGrid, $LIN, $COL)
        For $ii = 1 To $viz[0]
            $aPos = StringSplit($viz[$ii], $SEP, 2)
            Populate($ALL, $aPos[0], $aPos[1], $viz[$ii], $color, $parent)
        Next
    Else
        Local $iRedim = UBound($aInput, 1)
        ReDim $aInput[$iRedim + 1][5]
        $aInput[0][0] = $iRedim
        $aInput[$iRedim][0] = $LIN
        $aInput[$iRedim][1] = $COL
        $aInput[$iRedim][2] = $POS
        $aInput[$iRedim][3] = $color
        $aInput[$iRedim][4] = $iRedim

        $viz = __GetNeighbor($aGrid, $LIN, $COL)
        If $viz[0] >= 1 Then
            For $ii = 1 To $viz[0]
                $aPos = StringSplit($viz[$ii], $SEP, 2)
                Populate($ALL, $aPos[0], $aPos[1], $viz[$ii], $color, $iRedim)
            Next
        EndIf
    EndIf
    Return $iRedim
EndFunc   ;==>Populate

Func Colorate()
    For $ii = 1 To $ALL[0][0]
        If Not ($ii = $ALL[$ii][4]) Then
            GUICtrlSetBkColor($hArr[$ALL[$ii][0]][$ALL[$ii][1]], $ALL[$ii][3])
        EndIf
    Next
EndFunc   ;==>Colorate


While Sleep(25)
    $aMouse = GUIGetCursorInfo($hGui)
    If IsArray($aMouse) And $aMouse[3] And Not $aClick[1] Then
        $aClick[1] = $aMouse[4]
        Click_Left()
    ElseIf Not $aMouse[3] And $aClick[1] Then
        $aClick[1] = 0
    EndIf
WEnd

Func Click_Left()
    If $aClick[1] < $hArr[0][0] Or $aClick[1] > $hArr[UBound($aGrid, 1) - 1][UBound($hArr, 2) - 1] Then Return
    Local $arr = $oIndex.Item($aClick[1])
    ConsoleWrite(">" & _ArrayToString($arr, ",") & @LF)
    Switch $aGrid[$arr[0]][$arr[1]]
        Case 1
            $aGrid[$arr[0]][$arr[1]] = 0
            GUICtrlSetData($aClick[1], 0)
            GUICtrlSetBkColor($aClick[1], $OFF)
        Case Else
            $aGrid[$arr[0]][$arr[1]] = 1
            GUICtrlSetData($aClick[1], 1)
            GUICtrlSetBkColor($aClick[1], $ON)
    EndSwitch
EndFunc   ;==>Click_Left

Func _on_exit()
    GUISetState($hGui, @SW_HIDE)
    GUIDelete($hGui)
EndFunc   ;==>_on_exit

Func _quit()
    Exit
EndFunc   ;==>_quit

Func __GetNeighbor($aInput, $LIN, $COL)
    Local $aRet[1] = [0]

    $ax[0] = $LIN - 1
    $ax[0] = $ax[0] < 0 ? 0 : $ax[0]

    $ax[1] = $LIN + 1
    $ax[1] = $ax[1] > UBound($aInput, 1) - 1 ? UBound($aInput, 1) - 1 : $ax[1]

    $ay[0] = $COL - 1
    $ay[0] = $ay[0] < 0 ? 0 : $ay[0]

    $ay[1] = $COL + 1
    $ay[1] = $ay[1] > UBound($aInput, 2) - 1 ? UBound($aInput, 2) - 1 : $ay[1]

    For $yy = $ax[0] To $ax[1]
        For $xx = $ay[0] To $ay[1]
            If $aInput[$yy][$xx] And Not ($yy = $LIN And $xx = $COL) Then _ArrayAdd($aRet, $yy & $SEP & $xx)
        Next
    Next
    If UBound($aRet, 1) - 1 > 0 Then $aRet[0] = UBound($aRet, 1) - 1
    Return $aRet
EndFunc   ;==>__GetNeighbor

Func Color()
    Local $iRet
    Do
        $iRet = "0x" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2)
    Until $iRet <> $ON And $iRet <> $OFF
    Return $iRet
EndFunc   ;==>Color


; #FUNCTION# ====================================================================================================================
; Name ..........: GUICtrlGetBkColor
; Description ...: Retrieves the RGB value of the control background.
; Syntax ........: GUICtrlGetBkColor($hWnd)
; Parameters ....: $hWnd                - Control ID/Handle to the control
; Return values .: Success - RGB value
;                  Failure - 0
; Author ........: guinness
; Example .......: Yes
; ===============================================================================================================================
Func GUICtrlGetBkColor($hWnd)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    Local $hDC = _WinAPI_GetDC($hWnd)
    Local $iColor = _WinAPI_GetPixel($hDC, 0, 0)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    Return $iColor
EndFunc   ;==>GUICtrlGetBkColor

 

Edited by Luigi

Visit my repository

Posted (edited)

@Danyfirex, thank you for your reply, your thid link is very very useful!

I refatore the code work fine to small array.

Does not work with big array (not yet)!

 

;~ https://en.wikipedia.org/wiki/Connected-component_labeling
;~ #AutoIt3Wrapper_AU3Check_Parameters= -q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7
;~ #Tidy_Parameters=/sf

#include-once
#include <WinAPI.au3>
#include <Array.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>

#include <object_dump.au3>

OnAutoItExitRegister("_on_exit")

Opt("GUIOnEventMode", 1)
Opt("GUIEventOptions", 1)
Opt("MustDeclareVars", 1)

Global Const $SEP = "."
Global $aGuiSize[2] = [800, 600]
Global $sGuiTitle = "GuiTitle"
Global $hGui
Global $ax[2], $ay[2]
Global $iSize = 32
Global $ALL[1][5] = [[0]]
Global $viz, $iChield, $aPos

Global $POS, $iNext, $iSearch, $color

; grid or image
; 0 is transparency
; non-zero (value does not matter) is any color
Global $aGrid[][12] = [ _
        [0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0], _
        [0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1], _
        [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0], _
        [0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0], _
        [1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0], _
        [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], _
        [0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1], _
        [0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1], _
        [0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0], _
        [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0] _
        ]

Global $aGrid[][3] = [ _
        [1, 1, 0], _
        [1, 0, 0], _
        [0, 0, 0], _
        [0, 0, 1], _
        [0, 1, 1] _
        ]

; array to analise
Global $aMax[4] = [UBound($aGrid, 1), UBound($aGrid, 2)]
$aMax[2] = $aMax[0] - 1
$aMax[3] = $aMax[1] - 1

Global $hArr[$aMax[0]][$aMax[1]]
;~ _ArrayDisplay($hArr)

$hGui = GUICreate($sGuiTitle, $aGuiSize[0], $aGuiSize[1])
GUISetOnEvent($GUI_EVENT_CLOSE, "_quit")

For $LIN = 0 To $aMax[2]
    For $COL = 0 To $aMax[3]
        $hArr[$LIN][$COL] = GUICtrlCreateLabel($aGrid[$LIN][$COL], $iSize + $COL * $iSize, $iSize + $LIN * $iSize, $iSize, $iSize, BitOR($SS_SUNKEN, $SS_CENTER))
        $color = Color()
        GUICtrlSetBkColor($hArr[$LIN][$COL], $aGrid[$LIN][$COL] ? $color : 0xFFFFCC)
        If $aGrid[$LIN][$COL] Then Populate($ALL, $LIN, $COL, $LIN & $SEP & $COL, $color)
    Next
Next

;~ _ArrayDisplay($ALL, "Neighbors pixels", 0, 0, Default, "$LIN|$COL|$POS|$COLOR|$parent")

Func Populate(ByRef $aInput, $LIN, $COL, $POS, $color, $parent = 0)
    $iSearch = _ArraySearch($ALL, $POS, 1, Default, 0, 0, 0, 2)
    If Not @error Then Return
    $LIN = Number($LIN)
    $COL = Number($COL)
    If $parent Then
        Local $iRedim = UBound($aInput, 1)
        ReDim $aInput[$iRedim + 1][5]
        $aInput[0][0] = $iRedim
        $aInput[$iRedim][0] = $LIN
        $aInput[$iRedim][1] = $COL
        $aInput[$iRedim][2] = $POS
        $aInput[$iRedim][3] = $color
        $aInput[$iRedim][4] = $parent

        $viz = __GetNeighbor($aGrid, $LIN, $COL)
        If $viz[0] Then
            For $ii = 1 To $viz[0]
                $aPos = StringSplit($viz[$ii], $SEP, 2)
                Populate($ALL, $aPos[0], $aPos[1], $viz[$ii], $color, $parent)
            Next
        EndIf
    Else
        Local $iRedim = UBound($aInput, 1)
        ReDim $aInput[$iRedim + 1][5]
        $aInput[0][0] = $iRedim
        $aInput[$iRedim][0] = $LIN
        $aInput[$iRedim][1] = $COL
        $aInput[$iRedim][2] = $POS
        $aInput[$iRedim][3] = $color
        $aInput[$iRedim][4] = $iRedim

        $viz = __GetNeighbor($aGrid, $LIN, $COL)
        If $viz[0] >= 1 Then
            For $ii = 1 To $viz[0]
                $aPos = StringSplit($viz[$ii], $SEP, 2)
                Populate($ALL, $aPos[0], $aPos[1], $viz[$ii], $color, $iRedim)
            Next
        EndIf
    EndIf
    Return $iRedim
EndFunc   ;==>Populate

Func Colorate()
    For $ii = 1 To $ALL[0][0]
        If Not ($ii = $ALL[$ii][4]) Then
            GUICtrlSetBkColor($hArr[$ALL[$ii][0]][$ALL[$ii][1]], $ALL[$ii][3])
        EndIf
        ConsoleWrite($ii)
    Next
EndFunc   ;==>Colorate
Colorate()

GUISetState(@SW_SHOW, $hGui)

While Sleep(25)
WEnd

Func _on_exit()
    GUISetState($hGui, @SW_HIDE)
    GUIDelete($hGui)
EndFunc   ;==>_on_exit

Func _quit()
    Exit
EndFunc   ;==>_quit

Func __GetNeighbor($aInput, $LIN, $COL)
;~  ConsoleWrite("__GetPos($LIN=" & $LIN & ", $COL=" & $COL & " )" & @LF)
    Local $aRet[1] = [0]

    $ax[0] = $LIN - 1
    $ax[0] = $ax[0] < 0 ? 0 : $ax[0]

    $ax[1] = $LIN + 1
    $ax[1] = $ax[1] > UBound($aInput, 1) - 1 ? UBound($aInput, 1) - 1 : $ax[1]

    $ay[0] = $COL - 1
    $ay[0] = $ay[0] < 0 ? 0 : $ay[0]

    $ay[1] = $COL + 1
    $ay[1] = $ay[1] > UBound($aInput, 2) - 1 ? UBound($aInput, 2) - 1 : $ay[1]

    For $yy = $ax[0] To $ax[1]
        For $xx = $ay[0] To $ay[1]
            If $aInput[$yy][$xx] And Not ($yy = $LIN And $xx = $COL) Then _ArrayAdd($aRet, $yy & $SEP & $xx)
        Next
    Next
    If UBound($aRet, 1) - 1 > 0 Then $aRet[0] = UBound($aRet, 1) - 1
    Return $aRet
EndFunc   ;==>__GetNeighbor

Func Color()
    Return "0x" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2)
EndFunc   ;==>Color

 

Edited by Luigi

Visit my repository

Posted

what line did you mean?  You put the code in parts So Did. you mean this line ($viz = __GetNeighbor($aGrid, $LIN, $COL))

what's really your point? You have an png image for example this (back transparent):

YwAPi53.png

then get every picture alone. 

Saludos

Posted
Posted

as far I read about Moore neighborhood should split it. (an alternative for that blak/white picture should be replace color lol)

 

I'll look into Moore neighborhood algorith.

 

Saludos

Posted (edited)

Code updated: work fine (until now) with arrays.

;~ https://en.wikipedia.org/wiki/Connected-component_labeling
;~ #AutoIt3Wrapper_AU3Check_Parameters= -q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7
;~ #Tidy_Parameters=/sf

#include-once
#include <WinAPI.au3>
#include <Array.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>

#include <object_dump.au3>

OnAutoItExitRegister("_on_exit")

Opt("GUIOnEventMode", 1)
Opt("GUIEventOptions", 1)
Opt("MustDeclareVars", 1)

Global Const $SEP = "#"
Global $aGuiSize[2] = [800, 600]
Global $sGuiTitle = "GuiTitle"
Global $hGui
Global $ax[2], $ay[2]
Global $iSize = 32
Global $ALL[1][5] = [[0]]
Global $iChield, $aPos

Global $POS, $iNext, $iSearch, $color

; grid or image
; 0 is transparency
; non-zero (value does not matter) is any color
Global $aGrid[][12] = [ _
        [0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0], _
        [0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1], _
        [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0], _
        [0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0], _
        [1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0], _
        [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], _
        [0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1], _
        [0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1], _
        [0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0], _
        [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0] _
        ]

; array to analise
Global $aMax[4] = [UBound($aGrid, 1), UBound($aGrid, 2)]
$aMax[2] = $aMax[0] - 1
$aMax[3] = $aMax[1] - 1

Global $hArr[$aMax[0]][$aMax[1]]

$hGui = GUICreate($sGuiTitle, $aGuiSize[0], $aGuiSize[1])
GUISetOnEvent($GUI_EVENT_CLOSE, "_quit")
GUISetState(@SW_SHOW, $hGui)

For $LIN = 0 To $aMax[2]
    For $COL = 0 To $aMax[3]
        $hArr[$LIN][$COL] = GUICtrlCreateLabel($aGrid[$LIN][$COL], $iSize + $COL * $iSize, $iSize + $LIN * $iSize, $iSize, $iSize, BitOR($SS_SUNKEN, $SS_CENTER))
        $color = Color()
        GUICtrlSetBkColor($hArr[$LIN][$COL], $aGrid[$LIN][$COL] ? $color : 0xFFFFCC)
        GUICtrlSetTip($hArr[$LIN][$COL], $LIN & "," & $COL)
        If $aGrid[$LIN][$COL] Then Populate($ALL, $LIN, $COL, $LIN & $SEP & $COL, $color)
    Next
Next

Colorate()
;~ _ArrayDisplay($ALL, "Neighbors pixels", 0, 0, Default, "$LIN|$COL|$POS|$COLOR|$parent")

Func Populate(ByRef $aInput, $LIN, $COL, $POS, $color, $parent = 0)
    $iSearch = _ArraySearch($ALL, $POS, 1, Default, 0, 0, 2, 2)
    Local $viz
    If Not @error Then Return
    $LIN = Number($LIN)
    $COL = Number($COL)
    If $parent Then
        Local $iRedim = UBound($aInput, 1)
        ReDim $aInput[$iRedim + 1][5]
        $aInput[0][0] = $iRedim
        $aInput[$iRedim][0] = $LIN
        $aInput[$iRedim][1] = $COL
        $aInput[$iRedim][2] = $POS
        $aInput[$iRedim][3] = $color
        $aInput[$iRedim][4] = $parent

        $viz = __GetNeighbor($aGrid, $LIN, $COL)
        For $ii = 1 To $viz[0]
            $aPos = StringSplit($viz[$ii], $SEP, 2)
            Populate($ALL, $aPos[0], $aPos[1], $viz[$ii], $color, $parent)
        Next
    Else
        Local $iRedim = UBound($aInput, 1)
        ReDim $aInput[$iRedim + 1][5]
        $aInput[0][0] = $iRedim
        $aInput[$iRedim][0] = $LIN
        $aInput[$iRedim][1] = $COL
        $aInput[$iRedim][2] = $POS
        $aInput[$iRedim][3] = $color
        $aInput[$iRedim][4] = $iRedim

        $viz = __GetNeighbor($aGrid, $LIN, $COL)
        If $viz[0] >= 1 Then
            For $ii = 1 To $viz[0]
                $aPos = StringSplit($viz[$ii], $SEP, 2)
                Populate($ALL, $aPos[0], $aPos[1], $viz[$ii], $color, $iRedim)
            Next
        EndIf
    EndIf
    Return $iRedim
EndFunc   ;==>Populate

Func Colorate()
    For $ii = 1 To $ALL[0][0]
        If Not ($ii = $ALL[$ii][4]) Then
            GUICtrlSetBkColor($hArr[$ALL[$ii][0]][$ALL[$ii][1]], $ALL[$ii][3])
        EndIf
    Next
EndFunc   ;==>Colorate


While Sleep(25)
WEnd

Func _on_exit()
    GUISetState($hGui, @SW_HIDE)
    GUIDelete($hGui)
EndFunc   ;==>_on_exit

Func _quit()
    Exit
EndFunc   ;==>_quit

Func __GetNeighbor($aInput, $LIN, $COL)
    Local $aRet[1] = [0]

    $ax[0] = $LIN - 1
    $ax[0] = $ax[0] < 0 ? 0 : $ax[0]

    $ax[1] = $LIN + 1
    $ax[1] = $ax[1] > UBound($aInput, 1) - 1 ? UBound($aInput, 1) - 1 : $ax[1]

    $ay[0] = $COL - 1
    $ay[0] = $ay[0] < 0 ? 0 : $ay[0]

    $ay[1] = $COL + 1
    $ay[1] = $ay[1] > UBound($aInput, 2) - 1 ? UBound($aInput, 2) - 1 : $ay[1]

    For $yy = $ax[0] To $ax[1]
        For $xx = $ay[0] To $ay[1]
            If $aInput[$yy][$xx] And Not ($yy = $LIN And $xx = $COL) Then _ArrayAdd($aRet, $yy & $SEP & $xx)
        Next
    Next
    If UBound($aRet, 1) - 1 > 0 Then $aRet[0] = UBound($aRet, 1) - 1
;~  If $LIN = 3 And $COL = 7 Then _ArrayDisplay($aRet)
    Return $aRet
EndFunc   ;==>__GetNeighbor

Func Color()
    Return "0x" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2)
EndFunc   ;==>Color

 

Edited by Luigi

Visit my repository

  • Developers
Posted

@Blue_Drache, I have not example yet... Still work with (small) array yet.

If work fine for small array, I try with _GDIPlus_BitmapGetPixel and go to smile!

@Danyfirex, the man picture is a little irregular.

I want split this.

What exactly is the real purpose of all of this?

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Posted (edited)

 

I want split this.

For such a "simple" image you can use GDI+ and change the white color to a transparent color. Btw, the image has JPG artifacts which makes it much more difficult to get accurate results.

Or you can fill the white areas with a transparent color which is very slow with AutoIt (there is an example somewhere in this forum).

To extract the objects e.g. the image from post #4 you have to use some more complex algorithms. 

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

@Jos, the real purpose, is to have multiple images from a single image with the least possible space. As in the CSS from an image I have several other, but only in regular shapes, square with width and height. I knew I could draw pictures irregular, that was the challenge.
Now I can draw a picture, which is within another image.

Where will I use this? In my spare time, I develop my game developed in AutoIt, see this: https://www.youtube.com/watch?v=WeA7CsGi3Wk

I do not know if one day he'll be ready or if someone else (besides me) will play it, but this is my anti-depression medicine.

I know that automation games this forum is prohibited, and I respect and have never been against this rule.

But I can develop my game AutoIt?

Jos, I greatly cherish the AutoIt and the forum, you might be seeing something I'm not seeing.
But I do not see the harm in a Moore algorithm.

If you see something, I can not see, or forgot to any forum rule, please let me know.

I'm making a mistake?

Visit my repository

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...