在一副图片中填充一块封闭区域功能

一般采用种子法+递归。

简单说,就点像素点的周围4个点拿去计算和判断边界。

但是用递归实现的话,很容易就栈溢出了。

此时解决的办法,就是用栈+循环  (我比喻为 烧柴火,添柴火模式)

下面是实现代码

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <stack>
#include <queue>
using namespace std;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    this->DoubleBuffered = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Image1MouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
    TColor colorSource = Image1->Canvas->Pixels[X][Y];
    TColor colorDesc = clGreen;
    fillLoop(colorSource,colorDesc,X,Y);
}
//---------------------------------------------------------------------------
//这种递归的写法容易引发溢出
void TForm1::fill(TColor colorSource,TColor colorDesc,int X,int Y)
{
    if (X < 0 || X > Image1->Width)
    {
        return;
    }

    if (Y < 0 || Y > Image1->Height)
    {
        return;
    }

    if (Image1->Canvas->Pixels[X][Y] == colorDesc)
    {
        return;
    }


    if (Image1->Canvas->Pixels[X][Y] == colorSource)
    {
        Image1->Canvas->Pixels[X][Y] = colorDesc;

        TPoint p1(X-1,Y);
        TPoint p2(X,Y-1);
        TPoint p3(X+1,Y);
        TPoint p4(X,Y+1);

        fill(colorSource,colorDesc,p1.x,p1.y);
        fill(colorSource,colorDesc,p2.x,p2.y);
        fill(colorSource,colorDesc,p3.x,p3.y);
        fill(colorSource,colorDesc,p4.x,p4.y);
    }
}

//这是用栈+循环的方法
void TForm1::fillLoop(TColor colorSource,TColor colorDesc,int X,int Y)
{
    queue<TPoint> points;
    points.push(TPoint(X,Y));

    while (points.size() > 0)
    {
        TPoint p = points.front();
        points.pop();
        TColor color = Image1->Canvas->Pixels[p.x][p.y];
        if (color == colorDesc)
        {
            continue;
        }
        Application->ProcessMessages();
        Image1->Canvas->Pixels[p.x][p.y] = colorDesc;
        TPoint ps[4] = {TPoint(p.x-1,p.y),TPoint(p.x+1,p.y),TPoint(p.x,p.y-1),TPoint(p.x,p.y+1)};
        for (int i = 0 ;i < 4 ; i++)
        {
            if (Image1->Canvas->Pixels[ps[i].x][ps[i].y]
                == colorSource)
            {
                points.push(ps[i]);
            }
        }
    }
}

 

关于循环递归的问题

看这里

 

http://www.cnblogs.com/wb-DarkHorse/p/3284228.html

posted on 2016-08-15 15:31  zooz  阅读(2627)  评论(0编辑  收藏  举报