2015-09-05 91 views
1

我在java中制作一个像素艺术编辑器,只是为了好玩,而我遇到了一个问题。当我尝试填充函数时发生问题。这里是代码如何制作照片编辑器的填充方法?

private void fill(int x, int y){ 
    Color beforeColor = img[x][y]; 
    img[x][y] = foregroundColor; 

    if(x-1 >= 0){ 
     if(img[x-1][y] == beforeColor){ 
      fill(x-1, y); 
     } 
    } 

    if(x+1 >= 0){ 
     if(img[x+1][y] == beforeColor){ 
      fill(x+1, y); 
     } 
    } 

    if(y-1 >= 0){ 
     if(img[x][y-1] == beforeColor){ 
      fill(x, y-1); 
     } 
    } 

    if(y+1 >= 0){ 
     if(img[x][y+1] == beforeColor){ 
      fill(x, y+1); 
     } 
    } 
} 

img是awt Color对象的数组。

该方法基本上检查相同颜色的像素的指定像素周围,然后再次运行该方法进行下一个和下一个,直到整个区域被填充。

如果你知道计算机中的堆栈和递归的任何内容,那么你可能会意识到这将很快导致stackoverflowror并暂停程序。我试图弄清楚的是围绕递归的方式。有人能请我指出正确的方向围绕递归和stackoverflowerror?预先感谢能够帮助的人。

回答

1

可能是因为您可以使用一个列表:最初您将其填入要开始的像素。然后你有一个迭代循环,直到列表为空。在循环中,您从列表中取一个像素并检查其颜色。如果颜色匹配,则将其重新着色到列表中。如果颜色不匹配忽略像素。所以我会使用一个辅助类来存储像素的坐标。因此,它可能看起来像这样(一些错误检查,...可能会丢失,但这可能是一种方式):

class PixelCoordinate { 
    public int x; 
    public int y; 
    public PixelCoordinate(int x, int y) { 
     this.x = x; this.y = y; 
    } 
} 

Color beforeColor = img[x][y]; 
List<PixelCoordinate> worklist = new ArrayList<PixelCoordinate>(); 
// The pixel to start with 
worklist.add(new PixelCoordinate(x, y)); 
while (worklist.isEmpty() == false) { 
    // Take one pixel from the list 
    PixelCoordinate pixel = list.get(0); 
    list.remove(0); 

    // Check its color 
    if (img[x][y].equals(beforeColor) { 
     // Apply new color 
     img[x][y] = foregroundColor; 
     // Check neighbors 
     if (x-1 >= 0) { 
      list.add(new PixelCoordinate(x-y, y)); 
     } 
     // Add other neighbors... 
    } 
} 
+0

这是非常有帮助的,因为我通常不会使用列表,并会有从来没有想过这个。我确实改变了一些东西,因为我需要的东西存在一些错误/误解,但它效果很好。另外,为什么基本上使用Point对象的新类? – pokeyOne

+0

好吧,说实话,我从来没有找到那个班,当我需要它。除此之外,我经常想用坐标来存储额外的数据,在这种情况下,一个辅助类很容易实现 - 但是对于这种情况,Java Point类很​​好用。 – sleepy42