区域填充算法


一、区域填充算法(多边形转栅格)

分为两大类:

1、种子填色算法(Seed Filling)

这类算法建立在多边形边边界的图象形式数据之上,并还需提供多边形界内一点的坐标。所以,它一般只能用于人机交互填色,而难以用于程序填色。

GIS中用于栅格填色

2、扫描线填色算法(Scan-Line Filling)

这类算法建立在多边形边边界的矢量形式数据之上,可用于程序填色,也可用交互填色。


二、种子填色算法(Seed Filling)

种子填色又称边界填色(Boundary Filling)。

它的功能是:给出多边形光栅化后的边界位置及边界色代码boundary,以及多边形之内的一点x, y位置,要求将颜色color填满多边形。

算法分类

分为四邻法(4-connected)和八邻法。

C#实现

种子填充更适合用于栅格像元填色,知识有限。暂且用GDL+的矢量像元代替。

算法流程思路

:satisfied:自认为很棒的思路哈哈哈~:laughing:

代码实现(很巧(qi)妙(pa)的思路 :relieved: )

重要参数
  1. 需要填充颜色的图形的边界颜色:rainbow:

  2. 需要填充的颜色是什么:rainbow:

  3. 种子点,即填充图形内部中尚未填充颜色的任意一点,也是填充的起始点。:eight_pointed_black_star:

    (星星之火:fire:可以燎原呐~ )

具体思路

利用中点画圆算法(中点画圆算法文章中已详细阐述),画两个圆。

  • 第一个圆为目标填充圆,即,需要填充颜色的圆。
  • 第二个圆为取色圆,取其边界颜色,将其作为第一个圆填充的颜色。

其实要定义第一个圆的填充颜色,亦可用交互方式来定义,即用户自定义颜色。有点麻烦,不想搞那么花里胡哨的了。

代码

硬核算法部分

using System.Drawing;

namespace scan
{
    partial class Form1
    {
        public static void seedfill(Color boundcolor,Point pointseed,Color fillcolor,Bitmap bitmap)
        {
            //取出种子点(需要填充的图形边界内一点)的颜色
            Color c = bitmap.GetPixel(pointseed.X, pointseed.Y);

            //四邻法,对种子点的颜色进行判断。
            if (c!=fillcolor && c!=boundcolor)
            {
                bitmap.SetPixel(pointseed.X, pointseed.Y, fillcolor);
                seedfill(boundcolor, new Point(pointseed.X, pointseed.Y + 1), fillcolor, bitmap);
                seedfill(boundcolor, new Point(pointseed.X, pointseed.Y - 1), fillcolor, bitmap);
                seedfill(boundcolor, new Point(pointseed.X + 1, pointseed.Y), fillcolor, bitmap);
                seedfill(boundcolor, new Point(pointseed.X - 1, pointseed.Y), fillcolor, bitmap);
            }
        }
    }
}

使用部分

using System;
using System.Drawing;
using System.Windows.Forms;

namespace scan
{
    public partial class Form1 : Form
    {
        Graphics graphics;
        Bitmap bitmap;
        public Form1()
        {
            InitializeComponent();
            graphics = panel1.CreateGraphics();
            bitmap = new Bitmap(panel1.Width, panel1.Height);
        }
        private void ButtonDraw_Click(object sender, EventArgs e)
        {
            //第一个圆为填充图形
            circle(100, 100, 30, Color.Red);

            //第二个圆为取色图形
            circle(290, 200, 10, Color.Blue);

            graphics.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height);
        }
        private void ButtonFill_Click(object sender, EventArgs e)
        {
            //填充开始的点(种子点),为第一个圆的圆心。
            Point point = new Point(100, 100);

            //参数1图形边界颜色:取点(100,90)。
            //参数2开始填充的种子点:point(100,100).其为圆心。
            //参数3想要填充的颜色:取自第二个圆的边界颜色,即点(200,190)。
            //参数4在bitmap上进行操作。
            seedfill(bitmap.GetPixel(100, 70), point, bitmap.GetPixel(290, 190), bitmap);
            graphics.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height);
        }
    }
}

hhhhhh……

运行结果

:sunglasses:


文章作者: 李世昱
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 李世昱 !
评论
  目录