c++ Floodfill 算法最终错误

发布于 2024-11-05 20:55:47 字数 5250 浏览 0 评论 0 原文

我的洪水填充算法快完成了,但是某个地方有一个小错误,我花了大约3个小时调试,但我似乎找不到它!

笔记: 读入时我使用 0 到 15 的数字来定义墙壁

1 = 顶部 2 = 右 4 = 底部 8 = 左 (所以 13 意味着顶部/底部/左侧的墙壁在那里)

我的程序:

  • 它读取字段数来计算最大的房间(所以下面的所有内容都是一个循环,重复字段数)。

  • 然后它获取房间的尺寸

  • 现在在类字段中,它创建一个对象数组(Cell),用于存储周围的墙壁(左右下上),并且低于 16 的值

  • 现在这里是我认为问题来了,通过读取值std::cin

  • 读取值,然后当读入所有内容时,它会扫描空(0),然后创建一个房间,并检查其周围的可用空间(使用 wall-check)

  • 最后返回最大值,我们就完成了。

我使用的输入:

1
2 2
13 3
15 14

所以发生的情况是,在某个地方,在墙壁检查中,或者创建对象单元出了问题(我认为)

这是我的脚本,很抱歉不得不问这样的愚蠢问题!

提前致谢

    // een simpele floodfill

    #include <stdlib.h>
    #include <iostream>
    #include <bitset>


class Cell {

    private:
      int  kamer, value;
      bool left, right, up, down;

    public:            
      // constructor
      Cell::Cell() {};
      // functions
      bool CanLeft()      { return left ; }
      bool CanRight()     { return right; }
      bool CanDown()      { return down ; }
      bool CanUp()        { return up   ; }
      int  GetRoom()       { return kamer; }
      void SetRoom(int x)  { kamer = x   ; }      
      void SetValue(int x, int room=0) { value  = x;
                             kamer = room;
                             std::bitset<sizeof(int)> bits(value); 
                             if (bits[3]) left  = true;
                             else         left  = false;
                             if (bits[2]) down  = true;
                             else         down  = false;
                             if (bits[1]) right = true;
                             else         right = false;
                             if (bits[0]) up    = true;
                             else         up    = false;
                           }
};

class Field {

    private:
      int Biggest_Chamber;
      int Y;
      int X;
      int temp;
      Cell playfield[][1];

    public:
      // constructor
      Field::Field(int SizeY, int SizeX) {
                    Y = SizeY;
                    X = SizeX;
                    Cell playfield[SizeY-1][SizeX-1];
                    }
      // Create a 2d array and fill it

      void Get_input() {

           for (int Yas = 0; Yas < Y; Yas++){

               for (int Xas = 0; Xas < X; Xas++){

                   std::cin >> temp;
                   playfield[Yas][Xas].SetValue(temp);         
               }
           } 
      };  
      void Start() { Mark(0,0,1); }

      void Mark(int y, int x, int nr) {
                  std::cout << nr;
                  temp = nr;
                  playfield[y][x].SetRoom(nr);
                  if (playfield[y][x].CanLeft())   {
                     if (playfield[y][x-1].GetRoom() != 0) {
                                                    Mark(y, x-1, nr);
                                                    std::cout << nr;
                                                    system("pause");}}
                  if (playfield[y][x].CanDown()) {
                     if (playfield[y+1][x].GetRoom() != 0) {
                                                    Mark(y+1, x, nr);
                                                    std::cout << nr;
                                                    system("pause");}}
                  if (playfield[y][x].CanRight())  {
                     if (playfield[y][x+1].GetRoom() != 0) {
                                                    Mark(y, x+1, nr);
                                                    std::cout << nr;
                                                    system("pause");}}
                  if (playfield[y][x].CanUp())   {
                     if (playfield[y-1][x].GetRoom() != 0) {
                                                    Mark(y-1, x, nr);
                                                    std::cout << nr;
                                                    system("pause");}} 
                  for (int vertical = 0; vertical < Y; vertical++) {
                      for (int horizontal = 0; horizontal < X; horizontal++) {
                          if (playfield[vertical][horizontal].GetRoom() == 0) Mark(vertical, horizontal, nr+1);                   
                      }      
                  }
      }         
      int MaxValue() {
          int counter[temp];
          int max = 0;

          for (int y = 0; y < Y; y++) {
              for (int x = 0; x < X; x++) {
                  counter[playfield[y][x].GetRoom()]++;
              }
          }

          for (int i = 0; i < temp; i++)
          {
              if (counter[i] > max)
                 max = counter[i];
          }

          return max;
     }            
};


    int main() {
    using namespace std;


    int NrKamers;
    int sizeY;
    int sizeX;

    std::cin >> NrKamers;
    for (int i = 0; i < NrKamers; i++){

        std::cin >> sizeY >> sizeX;

        Field floodfield(sizeY, sizeX);
        floodfield.Get_input();
        floodfield.Start();

        std::cout << floodfield.MaxValue() << std::endl;
    }
    return 0;
}

My floodfilling algorithm is nearly finished, but there is a small error somewhere, I've spent about 3 hours debugging, but i can't seem to find it!

note:
When reading in I use numbers from 0 to 15 to define the walls

1 = top
2 = right
4 = bottom
8 = left
(so 13 would mean that the top/bottom/left walls are there)

My Program:

  • It reads in number of fields to calculate the biggest room from (so everything below here is a cycle that gets repeated for the number of fields).

  • Then it gets the room's dimensions

  • Now in the class field, it creates an array of objects (Cell) which store the walls around (left right down up), and a value below 16

  • Now here is where I think the problem comes, reading in values through std::cin

  • and then when everything is read in, it scans for empty (0), and then creates a room, and checks for availeble spaces around it (using the wall-check)

  • and at the end it returns the max value, and we are done.

The input I use:

1
2 2
13 3
15 14

so what happens is is that somewhere, in or the wall-check, or the creation of a object Cell something goes wrong (I think)

Here is my script, and sorry to have to ask something silly like this!

Thanks in advance

    // een simpele floodfill

    #include <stdlib.h>
    #include <iostream>
    #include <bitset>


class Cell {

    private:
      int  kamer, value;
      bool left, right, up, down;

    public:            
      // constructor
      Cell::Cell() {};
      // functions
      bool CanLeft()      { return left ; }
      bool CanRight()     { return right; }
      bool CanDown()      { return down ; }
      bool CanUp()        { return up   ; }
      int  GetRoom()       { return kamer; }
      void SetRoom(int x)  { kamer = x   ; }      
      void SetValue(int x, int room=0) { value  = x;
                             kamer = room;
                             std::bitset<sizeof(int)> bits(value); 
                             if (bits[3]) left  = true;
                             else         left  = false;
                             if (bits[2]) down  = true;
                             else         down  = false;
                             if (bits[1]) right = true;
                             else         right = false;
                             if (bits[0]) up    = true;
                             else         up    = false;
                           }
};

class Field {

    private:
      int Biggest_Chamber;
      int Y;
      int X;
      int temp;
      Cell playfield[][1];

    public:
      // constructor
      Field::Field(int SizeY, int SizeX) {
                    Y = SizeY;
                    X = SizeX;
                    Cell playfield[SizeY-1][SizeX-1];
                    }
      // Create a 2d array and fill it

      void Get_input() {

           for (int Yas = 0; Yas < Y; Yas++){

               for (int Xas = 0; Xas < X; Xas++){

                   std::cin >> temp;
                   playfield[Yas][Xas].SetValue(temp);         
               }
           } 
      };  
      void Start() { Mark(0,0,1); }

      void Mark(int y, int x, int nr) {
                  std::cout << nr;
                  temp = nr;
                  playfield[y][x].SetRoom(nr);
                  if (playfield[y][x].CanLeft())   {
                     if (playfield[y][x-1].GetRoom() != 0) {
                                                    Mark(y, x-1, nr);
                                                    std::cout << nr;
                                                    system("pause");}}
                  if (playfield[y][x].CanDown()) {
                     if (playfield[y+1][x].GetRoom() != 0) {
                                                    Mark(y+1, x, nr);
                                                    std::cout << nr;
                                                    system("pause");}}
                  if (playfield[y][x].CanRight())  {
                     if (playfield[y][x+1].GetRoom() != 0) {
                                                    Mark(y, x+1, nr);
                                                    std::cout << nr;
                                                    system("pause");}}
                  if (playfield[y][x].CanUp())   {
                     if (playfield[y-1][x].GetRoom() != 0) {
                                                    Mark(y-1, x, nr);
                                                    std::cout << nr;
                                                    system("pause");}} 
                  for (int vertical = 0; vertical < Y; vertical++) {
                      for (int horizontal = 0; horizontal < X; horizontal++) {
                          if (playfield[vertical][horizontal].GetRoom() == 0) Mark(vertical, horizontal, nr+1);                   
                      }      
                  }
      }         
      int MaxValue() {
          int counter[temp];
          int max = 0;

          for (int y = 0; y < Y; y++) {
              for (int x = 0; x < X; x++) {
                  counter[playfield[y][x].GetRoom()]++;
              }
          }

          for (int i = 0; i < temp; i++)
          {
              if (counter[i] > max)
                 max = counter[i];
          }

          return max;
     }            
};


    int main() {
    using namespace std;


    int NrKamers;
    int sizeY;
    int sizeX;

    std::cin >> NrKamers;
    for (int i = 0; i < NrKamers; i++){

        std::cin >> sizeY >> sizeX;

        Field floodfield(sizeY, sizeX);
        floodfield.Get_input();
        floodfield.Start();

        std::cout << floodfield.MaxValue() << std::endl;
    }
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

姜生凉生 2024-11-12 20:55:47

我没有太多时间来处理代码,但我的第一印象是您没有标记(或者更确切地说不使用标记)数组中的每个访问位置,以便您朝一个方向移动,并在处理另一个方向时位置你回到原来的方块。考虑测试的顺序:左、右、上、下;并且从左上角开始:

您不能向左移动,但可以向右移动。在第二个递归级别,您可以向左移动并返回到第一个方块。然后你不能向左移动,但你可以向右移动,所以你回到方格二,从那里你移动到方格一......无限。

在移动到下一个方格之前,您必须将您的方格标记为已访问,并检查您打算移动到的方格在当前运行中尚未被访问过。

分段错误是耗尽堆栈后无限递归的结果。

I have not had much time to deal with the code, but my first impression is that you are not marking (or rather not using the mark) each visited position in the array, so that you move in one direction, and while processing that other position you return back to the original square. Consider that the sequence of tests where: left, right, up, down; and that you start in the top-left corner:

You cannot move left, but you can move right. At that second recursion level you can move left and go back to square one. Then you cannot move left, but you can move right, so you go back to square two, from which you move to square one... infinitedly.

Before you move to the next square you have to mark your square as visited, and also check that the square you intend to move to has not been visited in the current run.

The segmentation fault is the result of infinite recursion, after you exhaust the stack.

栖迟 2024-11-12 20:55:47

2017 年 1 月 11 日:新版本;已成功测试两个位图。

我提出了我的 C 版本的 Flood-Fill 算法,它不使用递归调用,而仅使用新点偏移量的队列,它在窗口上工作:双缓冲区的 WinnOffs-(WinDimX,WinDimY) :*VBuffer(屏幕或图像的副本),并且可以选择写入洪水填充结果的掩码(*ExtraVBuffer)。
调用前ExtraVBuff必须填0(如果不需要掩码可以设置ExtraVBuff= NULL);在调用后使用它,您可以进行渐变填充或其他绘画效果。 NewFloodFill 适用于每像素 32 位,它是一个 C 函数。我在 1991 年重新发明了这个算法(我用 Pascal 编写了他的算法),但现在它可以在 C 语言中运行,每像素 32 位;也不使用任何函数调用,只在每次从队列中“弹出”后进行除法,并且永远不会溢出队列,如果它的大小正确(大约图像像素的 1/4),它允许始终正确填充任何区域;我在 c 函数 (FFILL.C) 之前显示,在测试程序 (TEST.C) 之后显示:

#define IMAGE_WIDTH 1024
#define IMAGE_HEIGHT 768
#define IMAGE_SIZE IMAGE_WIDTH*IMAGE_HEIGHT
#define QUEUE_MAX IMAGE_SIZE/4

typedef int T_Queue[QUEUE_MAX];
typedef int T_Image[IMAGE_SIZE];

void NewFloodFill(int X,
                  int Y,
                  int Color,
                  int BuffDimX,
                  int WinOffS,
                  int WinDimX,
                  int WinDimY,
                  T_Image VBuffer,
                  T_Image ExtraVBuff,
                  T_Queue MyQueue)

/* Replaces all pixels adjacent to the first pixel and equal to this;   */
/* if ExtraVBuff == NULL writes to *VBuffer (eg BUFFER of 786432 Pixel),*/
/* otherwise prepare a mask by writing on *ExtraVBuff (such BUFFER must */
/* always have the same size as *VBuffer (it must be initialized to 0)).*/

/*         X,Y: Point coordinates' of origin of the flood-fill.         */
/*     WinOffS: Writing start offset on *VBuffer and *ExtraVBuff.       */
/*    BuffDimX: Width, in number of Pixel (int), of each buffer.        */
/*     WinDimX: Width, in number of Pixel (int), of the window.         */
/*       Color: New color that replace all_Pixel == origin's_point.     */
/*     WinDimY: Height, in number of Pixel (int), of the window.        */
/*     VBuffer: Pointer to the primary buffer.                          */
/*  ExtraVBuff: Pointer to the mask buffer (can be = NULL).             */
/*     MyQueue: Pointer to the queue, containing the new-points' offsets*/

{
 int VBuffCurrOffs=WinOffS+X+Y*BuffDimX;
 int PixelIn=VBuffer[VBuffCurrOffs];
 int QueuePnt=0;
 int *TempAddr=((ExtraVBuff) ? ExtraVBuff : VBuffer);
 int TempOffs1;
 int TempX1;
 int TempX2;
 char FLAG;

 if (0<=X && X<WinDimX && 0<=Y && Y<WinDimY) do
  {
   /* Fill to left the current line */
   TempX2=X;
   while (X>=0 && PixelIn==VBuffer[VBuffCurrOffs])
    {
     TempAddr[VBuffCurrOffs--]=Color;
     --X;
    }
   TempOffs1=VBuffCurrOffs+1;
   TempX1=X+1;

   /* Fill to right the current line */
   VBuffCurrOffs+=TempX2-X;
   X=TempX2;
   while (X+1<WinDimX && PixelIn==VBuffer[VBuffCurrOffs+1])
    {
     ++X;
     TempAddr[++VBuffCurrOffs]=Color;
    }
   TempX2=X;

   /* Backward scan of the previous line; puts new points offset in Queue[] */
   if (Y>0)
    {
     FLAG=1;
     VBuffCurrOffs-=BuffDimX;
     while (X-->=TempX1)
      {
       if (PixelIn!=VBuffer[VBuffCurrOffs] ||
           ExtraVBuff && Color==ExtraVBuff[VBuffCurrOffs])
        FLAG=1;
       else
       if (FLAG)
        {
         FLAG=0;
         if (QueuePnt<QUEUE_MAX)
          MyQueue[QueuePnt++]=VBuffCurrOffs;
        } 
       --VBuffCurrOffs;
      }
    }

   /* Forward scan of the next line; puts new points offset in Queue[] */
   if (Y<WinDimY-1)
    {
     FLAG=1;
     VBuffCurrOffs=TempOffs1+BuffDimX;
     X=TempX1;
     while (X++<=TempX2)
      {
       if (PixelIn!=VBuffer[VBuffCurrOffs] ||
           ExtraVBuff && Color==ExtraVBuff[VBuffCurrOffs])
        FLAG=1;
       else
       if (FLAG)
        {
         FLAG=0;
         if (QueuePnt<QUEUE_MAX)
          MyQueue[QueuePnt++]=VBuffCurrOffs;
        }
       ++VBuffCurrOffs;
      }
    }

   /* Gets a new point offset from Queue[] */ 
   if (--QueuePnt>=0)
    {
     VBuffCurrOffs=MyQueue[QueuePnt];
     TempOffs1=VBuffCurrOffs-WinOffS;
     X=TempOffs1%BuffDimX;
     Y=TempOffs1/BuffDimX;
    }

  /* Repeat the main cycle until the Queue[] is not empty */
  } while (QueuePnt>=0);
}

这里是测试程序:

#include <stdio.h>
#include <malloc.h>
#include "ffill.c"

#define RED_COL 0xFFFF0000
#define WIN_LEFT 52
#define WIN_TOP 48
#define WIN_WIDTH 920
#define WIN_HEIGHT 672
#define START_LEFT 0
#define START_TOP 671

#define BMP_HEADER_SIZE 54

typedef char T_Image_Header[BMP_HEADER_SIZE];
void main(void)
{

 T_Image_Header bmpheader;
 T_Image *image;
 T_Image *mask;
 T_Queue *MyQueue;

 FILE *stream;
 char *filename1="ffill1.bmp";
 char *filename2="ffill2.bmp";
 char *filename3="ffill3.bmp";
 int bwritten;
 int bread;

 image=malloc(sizeof(*image));
 mask=malloc(sizeof(*mask));
 MyQueue=malloc(sizeof(*MyQueue));

 stream=fopen(filename1,"rb");
 bread=fread(&bmpheader, 1, BMP_HEADER_SIZE, stream);
 bread=fread((char *)image, 1, IMAGE_SIZE<<2, stream);
 fclose(stream);

 memset(mask,0,IMAGE_SIZE<<2);

 NewFloodFill(START_LEFT,
              START_TOP,
              RED_COL,
              IMAGE_WIDTH,
              IMAGE_WIDTH*WIN_TOP+WIN_LEFT,
              WIN_WIDTH,
              WIN_HEIGHT,
              *image,
              NULL,
              *MyQueue);

 stream=fopen(filename2,"wb+");
 bwritten=fwrite(&bmpheader, 1, BMP_HEADER_SIZE, stream);
 bwritten=fwrite((char *)image, 1, IMAGE_SIZE<<2, stream);
 fclose(stream);

 stream=fopen(filename3,"wb+");
 bwritten=fwrite(&bmpheader, 1, BMP_HEADER_SIZE, stream);
 bwritten=fwrite((char *)mask, 1, IMAGE_SIZE<<2, stream);
 fclose(stream);

 free(MyQueue);
 free(mask);
 free(image);
}

对于显示的测试程序的输入,我使用了以下 Windows 未压缩的 .BMP图片 (ffill1.bmp):

在此处输入图像描述

填充,由所示测试程序填充,如下(ffill2.bmp):

在此处输入图像描述

使用“mask”而不是 NULL,输出位图是 (ffill3.bmp):

在此处输入图像描述

1-11-2017: NEW-VERSION; SUCCESFULLY TESTED WITH TWO BITMAPS.

I propose my C version of the Flood-Fill algorithm, which doesn't uses recursive calls, but only a queue of the offsets of the new points, it works on the window: WinnOffs-(WinDimX,WinDimY) of the double-buffer: *VBuffer (copy of the screen or image) and, optionally, it write a mask of the flood-fill's result (*ExtraVBuff).
ExtraVBuff must be filled it with 0 before the call (if you don't need a mask you may set ExtraVBuff= NULL); using it after call you can do gradient floodfill or other painting effects. NewFloodFill works with 32 Bit per Pixel and it is a C function. I've reinvented this algorithm in 1991 (I wrote his in Pascal), but now it works in C with 32 Bit per Pixel; also not uses any functions calls, does only a division after each "pop" from queue, and never overflows the queue, that, if it is sized in the right way (about 1/4 of the pixels of the image), it allows always to fill correctly any area; I show before the c-function (FFILL.C), after the test program (TEST.C):

#define IMAGE_WIDTH 1024
#define IMAGE_HEIGHT 768
#define IMAGE_SIZE IMAGE_WIDTH*IMAGE_HEIGHT
#define QUEUE_MAX IMAGE_SIZE/4

typedef int T_Queue[QUEUE_MAX];
typedef int T_Image[IMAGE_SIZE];

void NewFloodFill(int X,
                  int Y,
                  int Color,
                  int BuffDimX,
                  int WinOffS,
                  int WinDimX,
                  int WinDimY,
                  T_Image VBuffer,
                  T_Image ExtraVBuff,
                  T_Queue MyQueue)

/* Replaces all pixels adjacent to the first pixel and equal to this;   */
/* if ExtraVBuff == NULL writes to *VBuffer (eg BUFFER of 786432 Pixel),*/
/* otherwise prepare a mask by writing on *ExtraVBuff (such BUFFER must */
/* always have the same size as *VBuffer (it must be initialized to 0)).*/

/*         X,Y: Point coordinates' of origin of the flood-fill.         */
/*     WinOffS: Writing start offset on *VBuffer and *ExtraVBuff.       */
/*    BuffDimX: Width, in number of Pixel (int), of each buffer.        */
/*     WinDimX: Width, in number of Pixel (int), of the window.         */
/*       Color: New color that replace all_Pixel == origin's_point.     */
/*     WinDimY: Height, in number of Pixel (int), of the window.        */
/*     VBuffer: Pointer to the primary buffer.                          */
/*  ExtraVBuff: Pointer to the mask buffer (can be = NULL).             */
/*     MyQueue: Pointer to the queue, containing the new-points' offsets*/

{
 int VBuffCurrOffs=WinOffS+X+Y*BuffDimX;
 int PixelIn=VBuffer[VBuffCurrOffs];
 int QueuePnt=0;
 int *TempAddr=((ExtraVBuff) ? ExtraVBuff : VBuffer);
 int TempOffs1;
 int TempX1;
 int TempX2;
 char FLAG;

 if (0<=X && X<WinDimX && 0<=Y && Y<WinDimY) do
  {
   /* Fill to left the current line */
   TempX2=X;
   while (X>=0 && PixelIn==VBuffer[VBuffCurrOffs])
    {
     TempAddr[VBuffCurrOffs--]=Color;
     --X;
    }
   TempOffs1=VBuffCurrOffs+1;
   TempX1=X+1;

   /* Fill to right the current line */
   VBuffCurrOffs+=TempX2-X;
   X=TempX2;
   while (X+1<WinDimX && PixelIn==VBuffer[VBuffCurrOffs+1])
    {
     ++X;
     TempAddr[++VBuffCurrOffs]=Color;
    }
   TempX2=X;

   /* Backward scan of the previous line; puts new points offset in Queue[] */
   if (Y>0)
    {
     FLAG=1;
     VBuffCurrOffs-=BuffDimX;
     while (X-->=TempX1)
      {
       if (PixelIn!=VBuffer[VBuffCurrOffs] ||
           ExtraVBuff && Color==ExtraVBuff[VBuffCurrOffs])
        FLAG=1;
       else
       if (FLAG)
        {
         FLAG=0;
         if (QueuePnt<QUEUE_MAX)
          MyQueue[QueuePnt++]=VBuffCurrOffs;
        } 
       --VBuffCurrOffs;
      }
    }

   /* Forward scan of the next line; puts new points offset in Queue[] */
   if (Y<WinDimY-1)
    {
     FLAG=1;
     VBuffCurrOffs=TempOffs1+BuffDimX;
     X=TempX1;
     while (X++<=TempX2)
      {
       if (PixelIn!=VBuffer[VBuffCurrOffs] ||
           ExtraVBuff && Color==ExtraVBuff[VBuffCurrOffs])
        FLAG=1;
       else
       if (FLAG)
        {
         FLAG=0;
         if (QueuePnt<QUEUE_MAX)
          MyQueue[QueuePnt++]=VBuffCurrOffs;
        }
       ++VBuffCurrOffs;
      }
    }

   /* Gets a new point offset from Queue[] */ 
   if (--QueuePnt>=0)
    {
     VBuffCurrOffs=MyQueue[QueuePnt];
     TempOffs1=VBuffCurrOffs-WinOffS;
     X=TempOffs1%BuffDimX;
     Y=TempOffs1/BuffDimX;
    }

  /* Repeat the main cycle until the Queue[] is not empty */
  } while (QueuePnt>=0);
}

Here there is the test program:

#include <stdio.h>
#include <malloc.h>
#include "ffill.c"

#define RED_COL 0xFFFF0000
#define WIN_LEFT 52
#define WIN_TOP 48
#define WIN_WIDTH 920
#define WIN_HEIGHT 672
#define START_LEFT 0
#define START_TOP 671

#define BMP_HEADER_SIZE 54

typedef char T_Image_Header[BMP_HEADER_SIZE];
void main(void)
{

 T_Image_Header bmpheader;
 T_Image *image;
 T_Image *mask;
 T_Queue *MyQueue;

 FILE *stream;
 char *filename1="ffill1.bmp";
 char *filename2="ffill2.bmp";
 char *filename3="ffill3.bmp";
 int bwritten;
 int bread;

 image=malloc(sizeof(*image));
 mask=malloc(sizeof(*mask));
 MyQueue=malloc(sizeof(*MyQueue));

 stream=fopen(filename1,"rb");
 bread=fread(&bmpheader, 1, BMP_HEADER_SIZE, stream);
 bread=fread((char *)image, 1, IMAGE_SIZE<<2, stream);
 fclose(stream);

 memset(mask,0,IMAGE_SIZE<<2);

 NewFloodFill(START_LEFT,
              START_TOP,
              RED_COL,
              IMAGE_WIDTH,
              IMAGE_WIDTH*WIN_TOP+WIN_LEFT,
              WIN_WIDTH,
              WIN_HEIGHT,
              *image,
              NULL,
              *MyQueue);

 stream=fopen(filename2,"wb+");
 bwritten=fwrite(&bmpheader, 1, BMP_HEADER_SIZE, stream);
 bwritten=fwrite((char *)image, 1, IMAGE_SIZE<<2, stream);
 fclose(stream);

 stream=fopen(filename3,"wb+");
 bwritten=fwrite(&bmpheader, 1, BMP_HEADER_SIZE, stream);
 bwritten=fwrite((char *)mask, 1, IMAGE_SIZE<<2, stream);
 fclose(stream);

 free(MyQueue);
 free(mask);
 free(image);
}

I've used, for the input of the test program shown, the follow Windows uncompressed .BMP image (ffill1.bmp):

enter image description here

Filled, by the test program shown, as follows (ffill2.bmp):

enter image description here

Using "mask" instead of NULL, the output bitmap is (ffill3.bmp):

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文