图像处理之泛洪填充算法(Flood Fill Algorithm) (六)

2014-11-24 11:22:24 · 作者: · 浏览: 30

{
push(x - 1, y1);
spanLeft = true;
}
else if(spanLeft && x > 0 && getColor(x - 1, y1) != oldColor)
{
spanLeft = false;
}
if(!spanRight && x < width - 1 && getColor(x + 1, y1) == oldColor) // just keep right line once in the stack
{
push(x + 1, y1);
spanRight = true;
}
else if(spanRight && x < width - 1 && getColor(x + 1, y1) != oldColor)
{
spanRight = false;
}
y1++;
}
}

}

public void floodFillScanLineWithStack(int x, int y, int newColor, int oldColor)
{
if(oldColor == newColor) {
System.out.println("do nothing !!!, filled area!!");
return;
}
emptyStack();

int y1;
boolean spanLeft, spanRight;
push(x, y);

while(true)
{
x = popx();
if(x == -1) return;
y = popy();
y1 = y;
while(y1 >= 0 && getColor(x, y1) == oldColor) y1--; // go to line top/bottom
y1++; // start from line starting point pixel
spanLeft = spanRight = false;
while(y1 < height && getColor(x, y1) == oldColor)
{
setColor(x, y1, newColor);
if(!spanLeft && x > 0 && getColor(x - 1, y1) == oldColor)// just keep left line once in the stack
{
push(x - 1, y1);
spanLeft = true;
}
else if(spanLeft && x > 0 && getColor(x - 1, y1) != oldColor)
{
spanLeft = false;
}
if(!spanRight && x < width - 1 && getColor(x + 1, y1) == oldColor) // just keep right line once in the stack
{
push(x + 1, y1);
spanRight = true;
}
else if(spanRight && x < width - 1 && getColor(x + 1, y1) != oldColor)
{
spanRight = false;
}
y1++;
}
}


}运行效果:

算法类源代码如下:


[java]
package com.gloomyfish.paint.fill;

import java.awt.image.BufferedImage;

import com.gloomyfish.filter.study.AbstractBufferedImageOp;

public class FloodFillAlgorithm extends AbstractBufferedImageOp {

private BufferedImage inputImage;
private int[] inPixels;
private int width;
private int height;

// stack data structure
private int maxStackSize = 500; // will be increased as needed
private int[] xstack = new int[maxStackSize];
private int[] ystack = new int[maxStackSize];
private int stackSize;

public FloodFillAlgorithm(BufferedImage rawImage) {
this.inputImage = rawImage;
width = rawImage.getWidth();
height = rawImage.getHeight();
inPixels = new int[width*height];
getRGB(rawImage, 0, 0, width, height, inPixels );
}

public BufferedImage getInputImage() {
return inputImage;
}

public void setInputImage(BufferedImage inputImage) {
this.inputImage = inputImage;
}

public int getColor(int x, int y)
{
int index = y * width + x;
return inPixels[index];
}

public void setColor(int x, int y, int newColor)
{
int index = y * width + x;
inPixels[index] = newColor;
}

public void updateResult()
{
setRGB( inputImage, 0, 0, width, height, inPixels );
}

/**
* it is very low calculation speed and cause the stack overflow issue when fill
* some big area and irregular shape. performance is very bad.
*
* @param x
* @param y
* @param newColor
* @param oldColor
*/
public void floodFill4(int x, int y, int newColor, int oldColor)
{
if