algorytm.org

Implementacja w C#

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Flood fill - Implementacja w C#
Ocena użytkownikóww: *****  / 2
SłabyŚwietny
Nadesłany przez Andrzej Borucki, 22 lutego 2012 21:30
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

FloodFill/Form1.cs:
// Algorytm FloodFill
// Andrzej Borucki BSD License
// www.algorytm.org

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Zainicjuj formularz
        /// </summary>
        private void Form1_Load(object sender, EventArgs e)
        {
            Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            pictureBox1.Image = bmp;
            ToolTip button1ToolTip = new ToolTip();
            button1ToolTip.SetToolTip(button1, "Standardowa metoda rekurencyjna");
            DrawText();
        }

        /// <summary>
        /// Wypisz litere "A"
        /// </summary>
        private void DrawText()
        {
            Bitmap bitmap = (Bitmap)pictureBox1.Image;
            Graphics g = Graphics.FromImage(bitmap);
            g.Clear(Color.White);
            using (Font myFont = new Font("Times New Roman", 100))
            {
                g.DrawString("A", myFont, Brushes.Black, new PointF(0, 0));
            }
            g.Dispose();
            pictureBox1.Invalidate();
        }

        /// <summary>
        /// Szuka pierwszego czarnego piksela
        /// </summary>
        /// <returns>Wspolrzedne pierwszego czarnego piksela</returns>
        private Point FindFirstBlack()
        {
            Bitmap bitmap = (Bitmap)pictureBox1.Image;
            for (int y = 0; y < bitmap.Height; y++)
                for (int x = 0; x < bitmap.Width; x++)
                {
                    Color cl = bitmap.GetPixel(x, y);
                    if ((cl.R == 0) && (cl.G == 0) && (cl.B == 0)) return new Point(x, y);
                }
            return new Point(0, 0);
        }

        /// <summary>
        /// 8-kierunkowy reukrencyjny algorytm FloodFill
        /// </summary>
        private void FloodFill(int x,int y)
        {
            Bitmap bitmap = (Bitmap)pictureBox1.Image;
            if ((x < 0) || (y < 0) || (x >= bitmap.Width) || (y >= bitmap.Height)) return;  //punkt x,y leży poza granicami
            Color cl = bitmap.GetPixel(x,y);
            if ((cl.R != 0) || (cl.G != 0) || (cl.B != 0)) return; //kolor x,y różny od koloru który chcemy zmieniać
            bitmap.SetPixel(x,y,Color.FromArgb(255,255,0,0));            
            Thread.Sleep(10);        //zatrzymaj watek na 10 ms. tak by uzytkownik widzial dzialanie algorytmu
            pictureBox1.Refresh();   //odswiez wyglad obrazka
            FloodFill(x, y - 1);     // wołanie procedury dla punktu powyżej       
            FloodFill(x + 1, y - 1); // dla punktu po ukosie prawo-powyżej
            FloodFill(x + 1, y);     // dla punktu z prawej strony
            FloodFill(x + 1, y + 1); // dla punktu po ukosie prawo-poniżej
            FloodFill(x, y + 1);     // dla punktu poniżej
            FloodFill(x - 1, y + 1); // dla punktu po ukosie lewo-poniżej
            FloodFill(x - 1, y);     // dla punktu z lewej strony
            FloodFill(x - 1, y - 1); // dla punktu po ukosie lewo-powyżej
        }

        /// <summary>
        /// Obsluga klikniecia buttona - rozpocznij wypelnianie
        /// </summary>
        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            DrawText();                 //wypisz litere A
            Point p = FindFirstBlack(); //znajdz pierwszy czarny piksel na obrazku
            FloodFill(p.X, p.Y);        //wypelnij wszystkie czarne piskele
            button1.Enabled = true;
        }
    }
}
Komentarze
photo
0 # Joey 2012-10-25 16:10
W języku c# rekurencja źle się kończy. W przypadku gdy zagnieżdża się wiele razy wyskakuje błąd. Gorąco odradzam stosowania tej metody!
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
0 # Borneq 2014-07-24 12:22
Jednak flood fill się przydaje, np. gdy mamy nieregularne spójne obszary, które mamy wyszukać na obrazie. Rekurencyjny floodfill bardzo obciążą stos, ale przygotowuję wkrótce iteracyjny algorytm floodfill.
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
0 # Ryszard1960 2019-04-30 12:21
Czy przygotowałeś już odpowiedni algorytm?
Odpowiedz | Odpowiedz z cytatem | Cytować
Dodaj komentarz