Ocena użytkownikóww: ***** / 3
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;
}
}
}