///<summary>initializes the FloodFill operation</summary>
        public static FloodFillRectangle FloodFill(Bitmap bmp, Point pt, Color color)
        {
            var c    = ToBgra(color);
            var rect = new FloodFillRectangle();

            //get the bits
            var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

            unsafe
            {
                //resolve pointer
                var scan0 = (byte *)(void *)bmpData.Scan0;
                //get the starting color
                //[loc += Y offset + X offset]
                var loc        = CoordsToIndex(pt.X, pt.Y, bmpData.Stride); //((bmpData.Stride*(pt.Y-1))+(pt.X*4));
                var startColor = *((int *)(scan0 + loc));

                //create the array of bools that indicates whether each pixel
                //has been checked.  (Should be bitfield, but C# doesn't support bitfields.)
                var pixelsChecked = new bool[bmpData.Width + 1, bmpData.Height + 1];
                LinearFloodFill4(scan0, pt.X, pt.Y, new Size(bmpData.Width, bmpData.Height), bmpData.Stride, (byte *)&startColor, c, pixelsChecked, ref rect);
            }
            bmp.UnlockBits(bmpData);
            return(rect);
        }
Exemple #2
0
        //***********
        //LINEAR ALGORITHM
        //***********
        private static unsafe void LinearFloodFill4( byte* scan0, int x, int y,Size bmpsize, int stride, byte* startcolor, int color, bool[,] pixelsChecked, ref FloodFillRectangle rect)
        {
            //offset the pointer to the point passed in
            var p=(int*) (scan0+(CoordsToIndex(x,y, stride)));

            //FIND LEFT EDGE OF COLOR AREA
            var lFillLoc=x; //the location to check/fill on the left
            var ptr=p; //the pointer to the current location
            while(true)
            {
                ptr[0]=color; 	 //fill with the color
                pixelsChecked[lFillLoc,y]=true;
                lFillLoc--; 		 	 //de-increment counter
                ptr-=1;				 	 //de-increment pointer
                if(lFillLoc<=0 || !CheckPixel((byte*)ptr,startcolor) ||  (pixelsChecked[lFillLoc,y]))
                    break;			 	 //exit loop if we're at edge of bitmap or color area

            }
            lFillLoc++;
            if (lFillLoc < rect.MinX)
                rect.MinX = lFillLoc;

            //FIND RIGHT EDGE OF COLOR AREA
            var rFillLoc=x; //the location to check/fill on the left
            ptr=p;
            while(true)
            {
                ptr[0]=color; //fill with the color
                pixelsChecked[rFillLoc,y]=true;
                rFillLoc++; 		 //increment counter
                ptr+=1;				 //increment pointer
                if(rFillLoc>=bmpsize.Width || !CheckPixel((byte*)ptr,startcolor) ||  (pixelsChecked[rFillLoc,y]))
                    break;			 //exit loop if we're at edge of bitmap or color area

            }
            rFillLoc--;
            if (rFillLoc > rect.MaxX)
                rect.MaxX = rFillLoc;

            if (y < rect.MinY)
                rect.MinY = y;
            if (y > rect.MaxY)
                rect.MaxY = y;

            //START THE LOOP UPWARDS AND DOWNWARDS
            ptr=(int*)(scan0+CoordsToIndex(lFillLoc,y,stride));
            for(var i=lFillLoc;i<=rFillLoc;i++)
            {
                //START LOOP UPWARDS
                //if we're not above the top of the bitmap and the pixel above this one is within the color tolerance
                if(y>0 && CheckPixel(scan0+CoordsToIndex(i,y-1,stride),startcolor) && (!(pixelsChecked[i,y-1])))
                    LinearFloodFill4(scan0, i,y-1,bmpsize,stride,startcolor, color, pixelsChecked, ref rect);
                //START LOOP DOWNWARDS
                if(y<(bmpsize.Height-1) && CheckPixel(scan0+CoordsToIndex(i,y+1,stride),startcolor) && (!(pixelsChecked[i,y+1])))
                    LinearFloodFill4(scan0, i,y+1,bmpsize,stride,startcolor, color, pixelsChecked, ref rect);
                ptr+=1;
            }
        }
Exemple #3
0
        ///<summary>initializes the FloodFill operation</summary>
        public static FloodFillRectangle FloodFill(Bitmap bmp, Point pt, Color color)
        {
            var c = ToBgra(color);
            var rect = new FloodFillRectangle();

            //get the bits
            var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            unsafe
            {
                //resolve pointer
                var scan0 = (byte*) (void*)bmpData.Scan0;
                //get the starting color
                //[loc += Y offset + X offset]
                var loc = CoordsToIndex(pt.X, pt.Y, bmpData.Stride); //((bmpData.Stride*(pt.Y-1))+(pt.X*4));
                var startColor = *((int*) (scan0 + loc));

                //create the array of bools that indicates whether each pixel
                //has been checked.  (Should be bitfield, but C# doesn't support bitfields.)
                var pixelsChecked = new bool[bmpData.Width + 1, bmpData.Height + 1];
                LinearFloodFill4(scan0, pt.X, pt.Y, new Size(bmpData.Width, bmpData.Height), bmpData.Stride, (byte*) &startColor, c, pixelsChecked, ref rect);
            }
            bmp.UnlockBits(bmpData);
            return rect;
        }
        //***********
        //LINEAR ALGORITHM
        //***********

        private static unsafe void LinearFloodFill4(byte *scan0, int x, int y, Size bmpsize, int stride, byte *startcolor, int color, bool[,] pixelsChecked, ref FloodFillRectangle rect)
        {
            //offset the pointer to the point passed in
            var p = (int *)(scan0 + (CoordsToIndex(x, y, stride)));


            //FIND LEFT EDGE OF COLOR AREA
            var lFillLoc = x;      //the location to check/fill on the left
            var ptr      = p;      //the pointer to the current location

            while (true)
            {
                ptr[0] = color;                  //fill with the color
                pixelsChecked[lFillLoc, y] = true;
                lFillLoc--;                      //de-increment counter
                ptr -= 1;                        //de-increment pointer
                if (lFillLoc <= 0 || !CheckPixel((byte *)ptr, startcolor) || (pixelsChecked[lFillLoc, y]))
                {
                    break;                                               //exit loop if we're at edge of bitmap or color area
                }
            }
            lFillLoc++;
            if (lFillLoc < rect.MinX)
            {
                rect.MinX = lFillLoc;
            }

            //FIND RIGHT EDGE OF COLOR AREA
            var rFillLoc = x;           //the location to check/fill on the left

            ptr = p;
            while (true)
            {
                ptr[0] = color;               //fill with the color
                pixelsChecked[rFillLoc, y] = true;
                rFillLoc++;                   //increment counter
                ptr += 1;                     //increment pointer
                if (rFillLoc >= bmpsize.Width || !CheckPixel((byte *)ptr, startcolor) || (pixelsChecked[rFillLoc, y]))
                {
                    break;                                       //exit loop if we're at edge of bitmap or color area
                }
            }
            rFillLoc--;
            if (rFillLoc > rect.MaxX)
            {
                rect.MaxX = rFillLoc;
            }

            if (y < rect.MinY)
            {
                rect.MinY = y;
            }
            if (y > rect.MaxY)
            {
                rect.MaxY = y;
            }


            //START THE LOOP UPWARDS AND DOWNWARDS
            ptr = (int *)(scan0 + CoordsToIndex(lFillLoc, y, stride));
            for (var i = lFillLoc; i <= rFillLoc; i++)
            {
                //START LOOP UPWARDS
                //if we're not above the top of the bitmap and the pixel above this one is within the color tolerance
                if (y > 0 && CheckPixel(scan0 + CoordsToIndex(i, y - 1, stride), startcolor) && (!(pixelsChecked[i, y - 1])))
                {
                    LinearFloodFill4(scan0, i, y - 1, bmpsize, stride, startcolor, color, pixelsChecked, ref rect);
                }
                //START LOOP DOWNWARDS
                if (y < (bmpsize.Height - 1) && CheckPixel(scan0 + CoordsToIndex(i, y + 1, stride), startcolor) && (!(pixelsChecked[i, y + 1])))
                {
                    LinearFloodFill4(scan0, i, y + 1, bmpsize, stride, startcolor, color, pixelsChecked, ref rect);
                }
                ptr += 1;
            }
        }