Click here to Skip to main content
Click here to Skip to main content
Go to top

WP7 FloodFill in Texture2D using Scan line Stack Algo

, 5 Feb 2012
Rate this:
Please Sign up or sign in to vote.
WP7 FloodFill in Texture2D using Scan line Stack Algo
If you are in WP7 XNA, might be somewhere you need to FloodFill in a texture2D.
 
I have a simple class that flood fills in texture2D.
 
This class is using FloodFill Scan line Stack algo. it fills the object in this
manner
using System;
 
using System.Collections.Generic;
using Microsoft.Xna.Framework;
 
public class FloodFill
    {
        Stack<Microsoft.Xna.Framework.Point> StkColoringPoints;
        
        public FloodFill()
        {
            StkColoringPoints = new Stack<Microsoft.Xna.Framework.Point>();
        }
 
        /// <summary>
        /// perform flood fill algorithm and return the updated buffer
        /// </summary>
        /// <param name="screenBuffer"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public Microsoft.Xna.Framework.Color[,] FloodFillToPoint(Microsoft.Xna.Framework.Color[,] screenBuffer, Vector2 point,Color newColor)
        {
            StkColoringPoints = new Stack<Microsoft.Xna.Framework.Point>();
            Microsoft.Xna.Framework.Point floodInvokePoint = new Microsoft.Xna.Framework.Point((int)point.X, (int)point.Y);
 
           return floodFillScanlineStack(screenBuffer, floodInvokePoint,newColor.PackedValue);
        }
        /// <summary>
        /// implements the flood fill scan line stack method to fill the color inside colosed boundry
        /// </summary>
        private Microsoft.Xna.Framework.Color[,] floodFillScanlineStack(Microsoft.Xna.Framework.Color[,] screenBuffer, Microsoft.Xna.Framework.Point floodInvokePoint, uint newColorCode)
        {
            uint oldColorCode = screenBuffer[floodInvokePoint.X, floodInvokePoint.Y].PackedValue;
 
            if (oldColorCode == newColorCode) 
                return screenBuffer;
 
            int y1;
            bool spanLeft, spanRight;
 
            int BUFFERWIDTH = screenBuffer.GetLength(0);
            int BUFFERHEIGHT = screenBuffer.GetLength(1);
 
            StkColoringPoints.Push(floodInvokePoint);
 
            while (StkColoringPoints.Count > 0)
            {
                floodInvokePoint = StkColoringPoints.Pop();
                y1 = floodInvokePoint.Y;
 
                while (y1 >= 0 && screenBuffer[floodInvokePoint.X, y1].PackedValue == oldColorCode) y1--;
                y1++;
                spanLeft = spanRight = false;
                while (y1 < BUFFERHEIGHT && screenBuffer[floodInvokePoint.X, y1].PackedValue == oldColorCode)
                {
                    screenBuffer[floodInvokePoint.X, y1].PackedValue = newColorCode;
                    if (!spanLeft && floodInvokePoint.X > 0 && screenBuffer[floodInvokePoint.X - 1, y1].PackedValue == oldColorCode)
                    {
                        StkColoringPoints.Push(new Microsoft.Xna.Framework.Point { X = floodInvokePoint.X - 1, Y = y1 });
                        spanLeft = true;
                    }
                    else if (spanLeft && floodInvokePoint.X > 0 && screenBuffer[floodInvokePoint.X - 1, y1].PackedValue != oldColorCode)
                    {
                        spanLeft = false;
                    }
                    if (!spanRight && floodInvokePoint.X < BUFFERWIDTH - 1 && screenBuffer[floodInvokePoint.X + 1, y1].PackedValue == oldColorCode)
                    {
                        StkColoringPoints.Push(new Microsoft.Xna.Framework.Point { X = floodInvokePoint.X + 1, Y = y1 });
                        spanRight = true;
                    }
                    else if (spanRight && floodInvokePoint.X < BUFFERWIDTH - 1 && screenBuffer[floodInvokePoint.X + 1, y1].PackedValue != oldColorCode)
                    {
                        spanRight = false;
                    }
                    y1++;
                }
            }
            return screenBuffer;
        }       
    }
 
Some utility functions:
private Microsoft.Xna.Framework.Color[,] ConvertTo2DArray(Microsoft.Xna.Framework.Color[] data, int columns, int rows)
        {
            Microsoft.Xna.Framework.Color[,] data2d = new Microsoft.Xna.Framework.Color[columns, rows];
            int counter = 0;
            for (int h = 0; h < rows; h++)
            {
                for (int w = 0; w < columns; w++)
                    data2d[w, h] = data[counter++];
            }
            return data2d;
        }
        private Microsoft.Xna.Framework.Color[] ConvertTo1DArray(Microsoft.Xna.Framework.Color[,] data2d)
        {
            Microsoft.Xna.Framework.Color[] data = new Microsoft.Xna.Framework.Color[data2d.Length];
            int counter = 0;
            for (int h = 0; h < data2d.GetLength(1); h++)
            {
                for (int w = 0; w < data2d.GetLength(0); w++)
                    data[counter++] = data2d[w, h];
            }
            return data;
        }
Assuming ColoringObject.Texture is your texture.
 
Microsoft.Xna.Framework.Color[] Texture1D = new  Microsoft.Xna.Framework.Color [ ColoringObject.Texture.Width * ColoringObject.Texture.Height];
            ColoringObject.Texture.GetData(Texture1D);
            FloodFill floodfill = new FloodFill(); 
            Microsoft.Xna.Framework.Color[,] Texture2D = ConvertTo2DArray(Texture1D, ColoringObject.Texture.Width, ColoringObject.Texture.Height);
            Texture2D = floodfill.FloodFillToPoint(Texture2D,touchPosition,this.fillingColor);
            Texture1D = ConvertTo1DArray(Texture2D);
 
            this.SpriteBatch.GraphicsDevice.Textures[0] = null;
            ColoringObject.Texture.SetData(Texture1D);
 
Happy coding...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

saboor awan
Software Developer (Senior)
Pakistan Pakistan
Expertise on Enterprise solutions, Mobile Apps & Services based applications on .NET platform. As Sr. Software Engineer, I have worked on variety of technologies like ASP.NET MVC, MS Windows Phone 7, WCF, and MS SharePoint 2010, MS Dynamics CRM.

Comments and Discussions

 
GeneralActually this algo flood fill the bitmap in this manner. htt... Pinmembersaboor awan13-Feb-12 7:04 
GeneralWhy do you use these spanLeft and spanRight flags ? PinmemberYvesDaoust6-Feb-12 20:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 5 Feb 2012
Article Copyright 2012 by saboor awan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid