【问题标题】:Flood fill algorithm洪水填充算法
【发布时间】:2009-12-10 08:09:20
【问题描述】:

我正在使用 Turbo C++ 在 C 语言中的一个简单图形库中工作,因为我正在开发一个非常原始的绘画风格程序版本,一切都很好,但我无法让洪水填充算法工作。我使用 4 路洪水填充算法,首先我尝试使用递归版本,但它只适用于小区域,填充大区域使其崩溃;阅读我发现实现它的显式堆栈版本可以解决问题,但我并没有真正看到它。

我开发了一个这样的堆栈:

struct node
{
    int x, y;
    struct node *next;
};

int push(struct node **top, int x, int y)
{
    struct node *newNode;
    newNode = (struct node *)malloc(sizeof(struct node));
    if(newNode == NULL) //If there is no more memory
        return 0;
    newNode->x = x;
    newNode->y = y;
    newNode->next = *top;
    *top = newNode;
    return 1; //If we push the element correctly
}

int pop(struct node **top, int &x, int &y)
{
    if(*top == NULL) //If the stack is empty
        return 0;
    struct node *temporal;
    temporal = *top;
    x = (*top)->x;
    y = (*top)->y;
    *top = (*top)->next;
    free(temporal);
    return 1; //If we pop an element 
}

这是我为洪水填充功能编写的代码:

void floodFill(int x, int y, int color_to_replace, int color_to_fill)
{
    if(color_to_replace == color_to_fill)
  return;
 struct node *stack = NULL;
 if(push(&stack, x, y) == 0) //If we can´t push the pixel
            return;
    while(pop(&stack, x, y) == 1) //While are pixels in the stack
    {
        pixel(x, y, color_to_fill);
        if(x+1 < 640 && read_pixel(x+1, y) == color_to_replace)
            if(push(&stack, x+1, y) == 0)
                return;
        if(x-1 >= 0 && read_pixel(x-1, y) == color_to_replace)
            if(push(&stack, x-1, y) == 0)
                return;
        if(y+1 < 480 && read_pixel(x, y+1) == color_to_replace)
            if(push(&stack, x, y+1) == 0)
                return;
        if(y-1 >= 0 && read_pixel(x, y-1) == color_to_replace)
            if(push(&stack, x, y-1) == 0)
                return;
    }
}

但它仍然不起作用,当我试图填充大面积区域时它会停止并且因为我在我的程序中使用分辨率 640 X 480 这真的是一个问题;任何想法为什么它不起作用?

【问题讨论】:

  • pop():你为什么分配temporal,然后仍然使用*top
  • 他需要时间来释放正确的顶部节点
  • 显式堆栈在堆栈非常有限的平台上解决它,例如 16 位 DOS。那里的递归算法简单不能深入。
  • 填充过程中什么时候停止?内存不足?

标签: c algorithm primitive flood-fill graphic


【解决方案1】:

不要将每个像素都压入堆栈,而是在将新位置压入堆栈之前尝试水平填充尽可能多的像素。请参阅Wikipedia article 进行讨论。

【讨论】:

    【解决方案2】:

    我在任何地方都没有看到任何边界检查...

    您确定 X 和 Y 值不会超出图片范围吗?

    编辑:

    额外的想法为什么它不能工作:

    • 读取和写入像素函数存在错误
    • 您返回的颜色值被放大到 32 位(因为例如您的图片是 16 位)并且您尝试再次写入和读取的颜色将不完全匹配。 (例如,你写了颜色:0xff00ff,但你回来了:0xf800f8,因为颜色是从 16 位放大的),这将导致洪水填充永远持续。

    【讨论】:

    • 我没有设置那个条件,因为我还在做测试,所以每次我运行程序时我都有最佳值,而且没有一个超出图片;例如画一个圆圈然后尝试填充它。但我现在要把它们放上去。
    猜你喜欢
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多