evilertoaster Posted July 15, 2006 Posted July 15, 2006 (edited) 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=16027where 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 EndFuncedit: WOW that code came out wrong...leme try and fix it just a secEdit2: ok that's wierd are the autoit code tags broken? Edited July 18, 2006 by evilertoaster
nitekram Posted July 15, 2006 Posted July 15, 2006 Edit2: ok that's wierd are the autoit code tags broken?I notice that the views are back (showing how many views), so maybe. 2¢ 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." 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
jvanegmond Posted July 17, 2006 Posted July 17, 2006 I have had the same problem many times. I don't have answers, and i couldn't figure out work arounds either. "Goto wasn't always bad" github.com/jvanegmond
evilertoaster Posted July 17, 2006 Author Posted July 17, 2006 No work around at all? So basically there's things that are logically impossible to code with AutoIt?"Goto wasn't always bad"True neither was the 8-track though...they are both past thier time
b8bboi Posted July 18, 2006 Posted July 18, 2006 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.
evilertoaster Posted July 18, 2006 Author Posted July 18, 2006 I'm not sure that will work... what if the part your filling in is shaped like a cosine graph or a cricle. All the pixels that are needed to shade are not adjacent to the starting point.
Moderators SmOke_N Posted July 18, 2006 Moderators Posted July 18, 2006 (edited) 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 Edit2:Can you not just make this all 1 function? It would easily take care of the recursive issue then. Edited July 18, 2006 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.
b8bboi Posted July 18, 2006 Posted July 18, 2006 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.)
evilertoaster Posted July 18, 2006 Author Posted July 18, 2006 Can you not just make this all 1 function? It would easily take care of the recursive issue then.I can't...if you can you'd be my hero becuase that would be all i'm trying to do.
evilertoaster Posted July 18, 2006 Author Posted July 18, 2006 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?
Moderators SmOke_N Posted July 18, 2006 Moderators Posted July 18, 2006 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.
evilertoaster Posted July 18, 2006 Author Posted July 18, 2006 That would be great! I made some comments on the code (it looks kinda bad untill you look at it in scite) and if you need anything else I'm all too eger to help!
Moderators SmOke_N Posted July 18, 2006 Moderators Posted July 18, 2006 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.
Moderators SmOke_N Posted July 19, 2006 Moderators Posted July 19, 2006 (edited) 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 ThenWouldn'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 July 19, 2006 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.
Moderators SmOke_N Posted July 20, 2006 Moderators Posted July 20, 2006 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 ;==>_PixelFillMaybe 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.
evilertoaster Posted July 20, 2006 Author Posted July 20, 2006 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 ThenWouldn'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Ü.®
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now