Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by jameshill88 · Mar 02, 2012 at 06:39 PM · coloralgorithmpaintfillflow

Flood fill algorithm for colour fill / paint bucket tool

Hi,

I need to write a flood fill algorithm using C# in Unity, in order to make a simple colour-fill tool similar to the one in MS paint. The user will be presented with a white texture with black line-drawings to be filled. They will pick a colour from a pallet, and click to fill sections of the line-drawing with colour. Black will always represent the boundary colour.

Here is the flood-fill method I have written. The code surrounding the sample is checked and works, but the algorithm seems to only fill one line to the left of the clicked pixel.

It would be great to get some advice on this, either to find out what is wrong with the existing code, or find another method of doing colour-fills. I think it's overflowing the stack.

EDIT: New version of code below, still with same problem:

 / FloodFill function

void FloodFill() {

 // TEST - colour the clicked pixel
 //_tex.SetPixel( (int)_pixelUV.x, (int)_pixelUV.y, m_fillColour );
 //_tex.SetPixel( _pixelX, _pixelY, m_fillColour );
 
     
 // FLOOD FILL 
 // ----------
 
 // Create WestEast
 List<Point> m_WestEast;
 
 //get the pixel's colour
 Color PC = new Color(_tex.GetPixel(m_StartNode.X, m_StartNode.Y).r, _tex.GetPixel(m_StartNode.X, m_StartNode.Y).g, _tex.GetPixel(m_StartNode.X, m_StartNode.Y).b);
     
 //Record clicked pixel as point
 Point node = new Point(m_StartNode.X, m_StartNode.Y);
     
 //if the pixel's colour is boundary colour (black), return.
 if(PC == Color.black)
 {
     return;
 }
     
 //else continue
     
 // Create a list Q[]
 m_List = new List<Point>();
     
 //add clicked pixel to Q[]
 m_List.Add(node);
 
 //for each element in Q[]
 for(int i=0; i<m_List.Count; i++)
 {
     //create new WE[] and add Q[n] to it
     m_WestEast = new List<Point>();
     m_WestEast.Add(node);
         
     //get pixel 1 to left (w) of Q[n]
     Point w = new Point(node.X + 1, node.Y);
     //get colour of w
     Color wCol = new Color(_tex.GetPixel(w.X, w.Y).r, _tex.GetPixel(w.X, w.Y).g, _tex.GetPixel(w.X, w.Y).b);    
         
     while(wCol != Color.black)
     {        
         //add pixel to WE[] and repeat
         m_WestEast.Add(w);
             
         //get new w
         w = new Point(w.X + 1, w.Y);
             
         //get colour of w
         wCol = new Color(_tex.GetPixel(w.X, w.Y).r, _tex.GetPixel(w.X, w.Y).g, _tex.GetPixel(w.X, w.Y).b);    
             
         //else if colour is boundary colour
             //go to next step
     }
 
     //get pixel 1 to right (e) of Q[n]
     Point e = new Point(node.X - 1, node.Y);
     //get colour of w
     Color eCol = new Color(_tex.GetPixel(e.X, e.Y).r, _tex.GetPixel(e.X, e.Y).g, _tex.GetPixel(e.X, e.Y).b);    
         
     while(eCol != Color.black)
     {        
         //add pixel to WE[] and repeat
         m_WestEast.Add(e);
             
         //get new e
         e = new Point(e.X - 1, e.Y);
             
         //get colour of e
         eCol = new Color(_tex.GetPixel(e.X, e.Y).r, _tex.GetPixel(e.X, e.Y).g, _tex.GetPixel(e.X, e.Y).b);    
             
         //else if colour is boundary colour
             //go to next step
     }
 
     //for each pixel in WE[]
     for(int j=0; j<m_WestEast.Count; j++)
     {
         //set the pixel to replacement colour
         _tex.SetPixel(m_WestEast[j].X, m_WestEast[j].Y, m_fillColour);
             
         //get pixel 1 to north (n) of Q[n]
         Point n = new Point(m_WestEast[j].X, m_WestEast[j].Y - 1);    
         
         //get colour of n
         Color nCol = new Color(_tex.GetPixel(n.X, n.Y).r, _tex.GetPixel(n.X, n.Y).g, _tex.GetPixel(n.X, n.Y).b);
         
         //if colour is not boundary colour
         if(nCol != Color.black)
         {
             //add pixel to Q[]
             m_List.Add(n);
         }
             
         //get pixel 1 to south (s) of Q[n]
         Point s = new Point(m_WestEast[j].X, m_WestEast[j].Y + 1);    
         
         //get colour of s
         Color sCol = new Color(_tex.GetPixel(s.X, s.Y).r, _tex.GetPixel(s.X, s.Y).g, _tex.GetPixel(s.X, s.Y).b);
             
         //if colour is not boundary colour
         if(sCol != Color.black)
         {
             //add pixel to Q[]
             m_List.Add(s);
         }
     }
 
 }
     
 // ----------

}

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image andreguilhermesodre · Oct 26, 2015 at 09:44 AM 0
Share

Hey @dchen05 you can share your solution again ?

avatar image Bunny83 andreguilhermesodre · Oct 26, 2015 at 01:29 PM 0
Share

The op wasn't online for over a year and dchen05 wasn't on for four months. His git hub account doesn't exist anymore. So it's very unlikely to get a response any time soon.

1 Reply

· Add your reply
  • Sort: 
avatar image
5

Answer by Bunny83 · Mar 04, 2012 at 05:09 AM

Ok, it seems you're trying to implement the second alternative floodfill algorithm on wikipedia but there are some things wrong or a bit messy:

  • First, GetPixel returns already a Color, why do you call it 3 times, take only one component at a time and then re-assemble them to a Color?
  • I'm not sure what "Point" you're using. If it's a struct (which it should be) you don't have to use new Point all the time you want to change a component of it. Since it's a value type every variable holds it's own copy of it.
  • Watch your texture boundary. First i thought you never check your coordinates, but GetPixel and SetPixel seems to be safe, thanks to Eric's comment.
  • SetPixel and GetPixel are quite slow functions. It's usually better to copy the texture into an array, do your operations and copy it back.
  • It seems you never read any of your stored nodes back. I guess you want a "node = m_List[i];" at the start of your main loop.
  • Don't forget to call texture.Apply() after you're done with your changes.

I've had some time and implemented the algorithm myself and created two extension methods FloodFillArea and FloodFillBorder if someone is interested.

Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Eric5h5 · Mar 04, 2012 at 06:53 AM 3
Share

Note that Get/SetPixel inherently check boundaries, depending on whether the texture is set to repeat or clamp.

avatar image Bunny83 · Mar 04, 2012 at 11:43 AM 0
Share

Good to know, thanks ;)

avatar image jameshill88 · Mar 04, 2012 at 06:25 PM 0
Share

Thanks, this is an excellent answer :) I'll have a go at making the recommended changes.

avatar image jameshill88 · Mar 04, 2012 at 06:26 PM 0
Share

Oh and you're exactly right, this is the floodfill from wikipedia

avatar image dchen05 · Apr 03, 2013 at 02:47 AM 0
Share

Hey @Bunny83, thanks for your work on this algorithm. I needed to add a tolerance factor for the color comparison for a project I'm working on. I created a Gist here incase anyone else wants to use it. https://gist.github.com/dchen05/5298031

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How do I implement a fill mechanism in a drawing game 0 Answers

How do I enter buildings into my map? 1 Answer

How to fill with translucent color the space between two lines in Unity3d? 1 Answer

Material doesn't have a color property '_Color' 4 Answers

Flood Fill algorithm implementation in C# problem 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges