/* < 扫描线种子填充算法 >
*
* 算法的基本过程如下:
* 当给定种子点(x, y)时,
* 首先分别向左和向右两个方向填充种子点所在扫描线上的位于给定区域的一个区段,
* 同时记下这个区段的范围[xLeft, xRight],
* 然后确定与这一区段相连通的上、下两条扫描线上位于给定区域内的区段,
* 并依次保存下来。反复这个过程,直到填充结束。
*
* 四个步骤实现算法:
* (1) 初始化一个空的栈用于存放种子点,将种子点(x, y)入栈;
* (2) 判断栈是否为空,如果栈为空则结束算法,否则取出栈顶元素作为当前扫描线的种子点(x, y),y是当前的扫描线;
* (3) 从种子点(x, y)出发,沿当前扫描线向左、右两个方向填充,直到边界。分别标记区段的左、右端点坐标为xLeft和xRight;
* (4) 分别检查与当前扫描线相邻的y - 1和y + 1两条扫描线在区间[xLeft, xRight]中的像素,
* 从xLeft开始向xRight方向搜索,若存在非边界且未填充的像素点,则找出这些相邻的像素点中最右边的一个,并将其作为种子点压入栈中,
* 然后返回第(2)步;
*
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
namespace MagicWandTool
{
class MagicWandTool
{
#region Private Field
private int _iThresholdValue = 0; //临界值大小([0,255])
private int _iImageWidth = 0; //原始图像的宽度
private int _iImageHeight = 0; //原始图像的高度
private IntPtr _ptrSourcePoint = IntPtr.Zero; //初始点指针
private IntPtr _ptrImageStartPoint = IntPtr.Zero; //初始点指针
private Dictionary<string, Point> _dicScannedSeed = new Dictionary<string, Point>(); //已经扫描过的种子点记录(用字典,是因为在要将某个种子点加入栈的时候,要判断这个种子点是否已经扫描过,在判断的时候,字典的速度比较快)
private Dictionary<string, Point> _dicBorderRegion = new Dictionary<string, Point>(); //所有边界点集合(用Dictionary可以方便的覆盖相同点,而不用比较,而如果用List,在List中查找元素是否存在效率很低)
private Stack<Point> _stackSeed = new Stack<Point>(); //保存种子点的栈
#endregion
#region Constructor
public MagicWandTool()
{
this._stackSeed = new Stack<Point>();
this._dicBorderRegion = new Dictionary<string, Point>();
this._dicScannedSeed = new Dictionary<string, Point>();
}
#endregion
#region Methods
#region Public Methods
public Point[] GetSelectRange(Image sourceImage,Point sourcePoint,int iThrehslodValue)
{
List<Point> listRange = new List<Point>();
try
{
#region 初始化各种变量
Bitmap sourceBitmap = new Bitmap(sourceImage);
this._iThresholdValue = iThrehslodValue;
this._iImageHeight = sourceBitmap.Height;
this._iImageWidth = sourceBitmap.Width;
BitmapData sourceBitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, this._iImageWidth, this._iImageHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
unsafe
{
this._ptrImageSt
区域填充:扫描线种子填充算法应用(类似魔术棒功能)
最新推荐文章于 2024-04-19 10:57:44 发布