我们已经知道有很多工具可以拿来画图,比如MFC
或者是OpenGL
都是画图很好的手段。这两个都是拥有很多适应方法的软件接口。但是我使用的是Easyx
这个更加方便便捷的工具。
该工具可以在如下页面下载,安装至相应的编译器即可。
http://www.easyx.cn/
下载完成之后记得安装Easyx
里面的Easyx_Help.chm
,这里面有许多我们开发会运用到的方法。
我们也知道种子填充算法需要获取点的颜色和在某个点再画上你需要的颜色,所以需要用到如下方法
//这个是为了获取某坐标点的颜色
COLORREF getpixel(int x, int y);
//这个是为了在某个点画上你想要的颜色
void putpixel(int x, int y, COLORREF color);
我们需要的是通过getpixel
方法来获取点的颜色,判断其是否与原颜色相同,如果不相同,则变化其颜色为新的 颜色,通过递归其4连通区域来达到有序在不越出区域的情况下,到达区域内的任意元素。
void FloodFill4_1(int x, int y, COLORREF oldcolor, COLORREF newcolor) {
try {
if (x > 100 && x < 300 && y > 100 && y < 300) {
if (getpixel(x, y) == oldcolor)
{
Sleep(1);
putpixel(x, y, newcolor);
FloodFill4_1(x, y + 1, oldcolor, newcolor);
FloodFill4_1(x, y - 1, oldcolor, newcolor);
FloodFill4_1(x - 1, y, oldcolor, newcolor);
FloodFill4_1(x + 1, y, oldcolor, newcolor);
}
}
}
catch (stack) {
}
}
扫描线填充可由以下4个步骤实现
(x,y)
入栈(x,y)
,以y作为当前扫描线。(x,y)
出发,沿当前扫描线向左、右两个方向填充,直到边界。分别标记区段的左、右端点坐标为xl
和xr
。[xl,xr]
中检查与当前扫描线y上、下相邻的两条扫描线上的像素。若存在非边界、未填充的像素,则把每一区间的最右像素作为种子点压入堆栈,返回第2步。 void ScanFill4(int x, int y, int oldcolor, int newcolor)
{
int xl, xr, i;
bool spanNeedFill;
Seed pt;
stack *stack1 = new stack();
InitStack(stack1);
pt.x = x;
pt.y = y;
Push(stack1, pt); //将前面生成的区段压入堆栈
while (!IsEmpty(stack1))
{
Sleep(10);
pt = Pop(stack1);
y = pt.y;
x = pt.x;
while (getpixel(x, y) == oldcolor)//向右填充
{
putpixel(x, y, newcolor);
x++;
}
xr = x - 1;
x = pt.x - 1;
while (getpixel(x, y) == oldcolor) //向左填充
{
putpixel(x, y, newcolor);
x--;
}
xl = x + 1;
//处理上一条扫描线
x = xl;
y = y + 1;
while (xfalse;
while (getpixel(x, y) == oldcolor)
{
spanNeedFill = true;
x++;
}
if (spanNeedFill)
{
pt.x = x - 1;
pt.y = y;
Push(stack1, pt);
spanNeedFill = false;
}
while (getpixel(x, y) != oldcolor && x//处理下一条扫描线,代码与处理上一条扫描线类似
x = xl;
y = y - 2;
while (xfalse;
while (getpixel(x, y) == oldcolor)
{
spanNeedFill = true;
x++;
}
if (spanNeedFill)
{
pt.x = x - 1;
pt.y = y;
Push(stack1, pt);
spanNeedFill = false;
}
while (getpixel(x, y) != oldcolor && x
上述算法对于每一个待填充区段,只需要压栈一次,而在递归算法中每一个像素都需要压栈一次。大大提高了区域填充的效率。
Project->Property->Linker->All Options中找到Stack Reserve Size 尽量将其调大就行了