Jump to content

Recursive function work around


Recommended Posts

Hi,

so i am writing a function for my bmp library and i've hit a bit of a road block.

I am trying to make a 'fill' function (like the one in mspaint only with the 'magic paintbrush' effect of photoshop). Problem is it relys on function recursion that is often broken by the 386 or whatever limit on funtion recursions. I've found this post from a while back- http://www.autoitscript.com/forum/index.php?showtopic=16027

where there was mention of removing this limit eventaully, but i guess that hasn't happened yet. So I guess my question is- 1. Is there any was around this limit or 2. How to restructure my fill loop without a recursive function.

Here is the code right now-

Func _PixelFill(ByRef $BMPHandle,$x,$y,$color,$variation=0)
    Local $CheckChart[UBound($BMPHandle,1)][UBound($BMPHandle,2)] ;This makes the check chart. It will be used to mark which pixels are already written
    Local $count=0; This is just a recursion couter i was using when trying to figure out when AutoIt would crash.
    Local $CheckColor=_PixelRead($BMPHandle,$x,$y); This will get the initial color to compare all the other ones agianst all the other ones. It i located at $X,$Y
    _PixelWrite($BMPHandle,$x,$y,$color);This writes the pixel at X,Y and uses the color specified (all colors are given and returned in the form "RRGGBB"
    $CheckChart[$x][$y]=1; We just wrote a pixel so let's mark it on the check chart so it doesn't get written agian.
    For $a=-1 to 1
        for $b=-1 to 1   ; this for loop will start going though every pixel touching X,Y (the on to the left -1,0  to the right 1,0   above 0,1 and below  0,-1 and diagonals
            if $CheckColor>=Dec(_PixelRead($BMPHandle,$x+$a,$y+$B))-$variation or $CheckColor<=Dec(_PixelRead($BMPHandle,$x+$a,$y+$B))-$variation Then ;checks if the color at some point is within the allowed variation
                $CheckChart[$x+$a][$y+$b]=1; if it is, mark it as written (is not written yes but we call PixelBomp in 2 lines which does write)
                $count+=1
                PixelBomb($BMPHandle,$x+$a,$y+$b,$color,$count,$CheckChart,$CheckColor,$variation); calls pixelbomb
            EndIf
        Next
    Next
    Return $count
EndFunc
Func PixelBomb(ByRef $BMPHandle,$x,$y,ByRef $color,ByRef $count,ByRef $CheckChart,ByRef $CheckColor,$variation=0)
    _PixelWrite($BMPHandle,$x,$y,$color); Writes the pixel x,y
    For $a=-1 to 1
        for $b=-1 to 1; same structure as above
            if $x+$a<0 or $y+$b<0 or $x+$a>UBound($BMPHandle,1)-1 or $y+$b>UBound($BMPHandle,2)-1 then ContinueLoop; if its at the border of the BMP (X or Y<0 or X or Y > width or height) then skip it
            if ($CheckColor=Dec(_PixelRead($BMPHandle,$x+$a,$y+$B))-$variation or $CheckColor=Dec(_PixelRead($BMPHandle,$x+$a,$y+$B))-$variation) and $CheckChart[$x+$a][$y+$b]<>1 Then ; checks if the pixel is within the allowed variation and hasn't already been written yet
                $CheckChart[$x+$a][$y+$b]=1; if everything checks out, mark the pixel and being written (calls PixelBomb in 2 lines)
                $count+=1
                PixelBomb($BMPHandle,$x+$a,$y+$b,$color,$count,$CheckChart,$CheckColor,$variation)
            EndIf
        Next
    Next
EndFunc

edit: WOW that code came out wrong...leme try and fix it just a sec

Edit2: ok that's wierd are the autoit code tags broken?

Edited by evilertoaster
Link to comment
Share on other sites

Edit2: ok that's wierd are the autoit code tags broken?

I notice that the views are back (showing how many views), so maybe.

All by me:

"Sometimes you have to go back to where you started, to get to where you want to go." 

"Everybody catches up with everyone, eventually" 

"As you teach others, you are really teaching yourself."

From my dad

"Do not worry about yesterday, as the only thing that you can control is tomorrow."

 

WindowsError.gif

WIKI | Tabs; | Arrays; | Strings | Wiki Arrays | How to ask a Question | Forum Search | FAQ | Tutorials | Original FAQ | ONLINE HELP | UDF's Wiki | AutoIt PDF

AutoIt Snippets | Multple Guis | Interrupting a running function | Another Send

StringRegExp | StringRegExp Help | RegEXTester | REG TUTOR | Reg TUTOT 2

AutoItSetOption | Macros | AutoIt Snippets | Wrapper | Autoit  Docs

SCITE | SciteJump | BB | MyTopics | Programming | UDFs | AutoIt 123 | UDFs Form | UDF

Learning to script | Tutorials | Documentation | IE.AU3 | Games? | FreeSoftware | Path_Online | Core Language

Programming Tips

Excel Changes

ControlHover.UDF

GDI_Plus

Draw_On_Screen

GDI Basics

GDI_More_Basics

GDI Rotate

GDI Graph

GDI  CheckExistingItems

GDI Trajectory

Replace $ghGDIPDll with $__g_hGDIPDll

DLL 101?

Array via Object

GDI Swimlane

GDI Plus French 101 Site

GDI Examples UEZ

GDI Basic Clock

GDI Detection

Ternary operator

Link to comment
Share on other sites

This is not fast but it'll work. You can use an array. Start with one pixel. Then keep adding adjacent pixels to the array provided that they are not already in the array itself (this checking part makes it slow). Do it until you can't add adjacent pixels any more due to all of them being already in the array.

To make it faster, you can use a 2 dimensional array the size of the screen to mark whether a pixel has already been added or not.

Link to comment
Share on other sites

  • Moderators

I've looked over your functions several times since you've posted this, and they really make no sense to me... Why do you have For $b = 1 to 1? That's not a loop. If you could clean it up a bit... I'd take a look, but right now it kind of gives me a headache with everything so close trying to figure out what your doing.

Edit:

See how confused I was... it's $b = -1 To 1 :D

Edit2:

Can you not just make this all 1 function? It would easily take care of the recursive issue then.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I'm not exactly following you. You're trying to make a tool that works exactly like the Fill tool in Photoshop right? Then all pixels must be "connected" to each other either directly or through other pixels of the same shade. The primary logic is still the same as your recursive function. The only difference is you use an array to hold the coordinates of the pixels instead of local variables within a recursive function.

From a programming stand point, every recursive function can be simulated using a stack. (That's how they're actually implemented in the first place.)

Link to comment
Share on other sites

I'm not exactly following you. You're trying to make a tool that works exactly like the Fill tool in Photoshop right? Then all pixels must be "connected" to each other either directly or through other pixels of the same shade. The primary logic is still the same as your recursive function. The only difference is you use an array to hold the coordinates of the pixels instead of local variables within a recursive function.

Humm well I'll think hard on what you say...it's not clicking for me just yet but give it a sec...can you maybe give some psuedo code for what your talking about?
Link to comment
Share on other sites

  • Moderators

I can't...if you can you'd be my hero becuase that would be all i'm trying to do.

I don't mind helping out... but a detailed list on what you want to do or what each line is supposed to do would be great along with "all the functions" tht your using there... ie _PixelWrite() / _PixelRead() would be great...

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

Ok, I'll have a look tomorrow, I'm out for the evening.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

Can you show me the _PixelRead() and _PixelWrite() functions... or PM them to me?

Edit:

P.S. - Maybe I'm missing something but this statement doesn't make any sense to me:

if $CheckColor>=Dec(_PixelRead($BMPHandle,$x+$a,$y+$b))-$variation or $CheckColor<=Dec(_PixelRead($BMPHandle,$x+$a,$y+$b))-$variation Then
Wouldn't that condition always be true?

Edit2:

In the PixelBomb() - Same as above question:

if ($CheckColor=Dec(_PixelRead($BMPHandle,$x+$a,$y+$b))-$variation or $CheckColor=Dec(_PixelRead($BMPHandle,$x+$a,$y+$b))-$variation)
Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

Man, I'll be honest, I'm so confused on what this does, so here's an attempt with a couple of comments... I'd feel better if maybe I/We talked about let's do something for this, and maybe throw some ideas back and forth.

Func _PixelFill(ByRef $BMPHandle, $x, $Y, $color, $variation = 0)
    Local $CheckChart[UBound($BMPHandle, 1)][UBound($BMPHandle, 2)]
    Local $count = 0
    Local $CheckColor = _PixelRead($BMPHandle, $x, $Y);PixelRead should be in this function too to avoid recursive since it's in a loop
    _PixelWrite($BMPHandle, $x, $Y, $color)
    $CheckChart[$x][$Y] = 1
    For $a = -1 To 1
        For $b = -1 To 1
            Local $_PixelReadValue = Dec(_PixelRead($BMPHandle, $x + $a, $Y + $B))
            If $CheckColor >= ($_PixelReadValue - $variation) Then
                $CheckChart[$x + $a][$Y + $b] = 1
                $count += 1
                $PBombA = - 2
                _PixelWrite($BMPHandle, $x, $Y, $color);Should also have this in here from the function itself rather than calling it
                While $PBombA <= 1;Should be the equivlent all the way to the WEnd ... Of the PixelBomb() function
                    $PBombA += 1
                    For $PBombB = - 1 To 1
                        If $x + $PBombA < 0 Or $Y + $PBombB < 0 Or $x + $PBombA > (UBound($BMPHandle, 1) - 1) Or  _
                                $Y + $PBombB > (UBound($BMPHandle, 2) - 1) Then ContinueLoop
                        $_PixelReadValue2 = Dec(_PixelRead($BMPHandle,$x + $PBombA, $Y + $PBombB)) 
                        If  $CheckColor = ($_PixelReadValue2 - $variation) And  _
                                $CheckChart[$x + $PBombA][$Y + $PBombB] <> 1 Then 
                            $CheckChart[$x + $PBombA][$Y + $PBombB] = 1
                            $count += 1
                            $PBombA = - 2
                            ExitLoop
                        EndIf
                    Next
                WEnd
            EndIf
        Next
    Next
    Return $count
EndFunc   ;==>_PixelFill
Maybe this will help you understand what I meant at least of combining them.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Can you show me the _PixelRead() and _PixelWrite() functions... or PM them to me?

Edit:

P.S. - Maybe I'm missing something but this statement doesn't make any sense to me:

if $CheckColor>=Dec(_PixelRead($BMPHandle,$x+$a,$y+$b))-$variation or $CheckColor<=Dec(_PixelRead($BMPHandle,$x+$a,$y+$b))-$variation Then
Wouldn't that condition always be true?

Edit2:

In the PixelBomb() - Same as above question:

if ($CheckColor=Dec(_PixelRead($BMPHandle,$x+$a,$y+$b))-$variation or $CheckColor=Dec(_PixelRead($BMPHandle,$x+$a,$y+$b))-$variation)
Here's the functions you asked for-

Func _PixelRead(ByRef $BMPHandle,$x,$y)
    Local $Width=UBound($BMPHandle,1)
    Local $Height=UBound($BMPHandle,2)
    If $x>$Width-1 Or $x<0 Or $y>$Height-1 Or $y<0 Then Return (-1)
    Local $type=Opt("ColorMode")
    If $type=1 Then
        $color=$BMPHandle[$x][$y]
    Else
        $temp=$BMPHandle[$x][$y]
        $color=StringMid($temp, 5, 2) & StringMid($temp, 3, 2) & StringMid($temp, 1, 2)
    EndIf
    If $color="" Then $Color="FFFFFF"
    Return $Color
EndFuncoÝ÷ Ù«­¢+ÙÕ¹}A¥á±]ɥѡ   åIÀÌØí 5A!¹±°ÀÌØíà°ÀÌØíä°ÀÌØí½±½È¤(%1½°ÀÌØí]¥Ñ õU ½Õ¹ ÀÌØí 5A!¹±°Ä¤(%1½°ÀÌØí!¥¡ÐõU  ½Õ¹ ÀÌØí 5A!¹±°È¤(%%ÀÌØíàÐìÀÌØí]¥Ñ ´Ä=ÈÀÌØíà±ÐìÀ=ÈÀÌØíäÐìÀÌØí!¥¡Ð´Ä=ÈÀÌØíä±ÐìÀQ¡¸IÑÕɸ ´Ä¤(%1½°ÀÌØíÑåÁõ=ÁÐ ÅÕ½Ðí
½±½É5½ÅÕ½Ðì¤(%%ÀÌØíÑåÁôÄQ¡¸($$ÀÌØí    5A!¹±lÀÌØíáulÀÌØíåtôÀÌØí½±½È(%±Í($$ÀÌØí  5A!¹±lÀÌØíáulÀÌØíåtõMÑÉ¥¹5¥ ÀÌØí½±½È°Ô°È¤µÀìMÑÉ¥¹5¥ ÀÌØí½±½È°Ì°È¤µÀìMÑÉ¥¹5¥ ÀÌØí½±½È°Ä°È¤(%¹%(%IÑÕɸ Ĥ)¹Õ¹oÝ÷ Ù8^Êèm¦åË
'ßÛazZr¢ëh¢kéåzË2¢é'£hÂl¥ºÚ¯,(®KºØ­q©à÷²¢æ§×N[azÊ.­Ç¡×¢»aÇ·¢éÝêÞnÜ.®
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...