Flood Fill, como deixar menos custoso?

6 respostas
V

Galera, eu implementei aqui o Flood Fill:

public void floodFill(int x, int y, Color target_color, Color replacement_color) { Stack<Integer[]> q = new Stack<Integer[]>(); if (imageBuffer.getRGB(x, y) == replacement_color.getRGB()) return; q.push(new Integer[] { x, y }); while (!q.isEmpty()) { Integer[] n = q.peek(); imageBuffer.setRGB(n[0], n[1], replacement_color.getRGB()); q.pop(); if (imageBuffer.getRGB(n[0] - 1, n[1]) == target_color.getRGB()) { q.push(new Integer[] { n[0] - 1, n[1] }); } if (imageBuffer.getRGB(n[0] + 1, n[1]) == target_color.getRGB()) { q.push(new Integer[] { n[0] + 1, n[1] }); } if (imageBuffer.getRGB(n[0], n[1] - 1) == target_color.getRGB()) { q.push(new Integer[] { n[0], n[1] - 1 }); } if (imageBuffer.getRGB(n[0], n[1] + 1) == target_color.getRGB()) { q.push(new Integer[] { n[0], n[1] + 1 }); } } }

Tem a versão recursiva tbm:

public void floodFill0(int x, int y, Color target_color, Color replacement_color) { if (imageBuffer.getRGB(x, y) != target_color.getRGB()) { return; } imageBuffer.setRGB(x, y, replacement_color.getRGB()); floodFill0(x - 1, y, target_color, replacement_color); floodFill0(x + 1, y, target_color, replacement_color); floodFill0(x, y - 1, target_color, replacement_color); floodFill0(x, y + 1, target_color, replacement_color); }

A recursiva n é muito boa, pq quando a tela a ser pintada é muito grande, da Stack Overflow…

O primeiro ali de cima, iterativo funciona perfeitamente só que esta meio custoso, ele demora poco mais de 1 segundo pra pintar uma tela de 750x550…
Seria culpa da JVM do java que faz com que ele fique lerdo, ou tteria alguma implementação menos custosa que voces podem me passar ?

6 Respostas

V
Gente, sera que alguem poderia me ajudar ? Eu fiz uma outra implementação mas só economizando codigo desta forma, mas ainda esta custosa:
private int[] dx = { -1, 0, 1, 0 };
	private int[] dy = { 0, 1, 0, -1 };

	public void floodFill(int x, int y, Color target_color, Color replacement_color) {
		Stack<Integer[]> stack = new Stack<Integer[]>();
		if (imageBuffer.getRGB(x, y) == replacement_color.getRGB())
			return;
		stack.push(new Integer[] { x, y });
		while (!stack.isEmpty()) {
			Integer[] aux = stack.peek();
			imageBuffer.setRGB(aux[0], aux[1], replacement_color.getRGB());
			stack.pop();
			for (int i = 0; i < 4; i++) {
				if (imageBuffer.getRGB(aux[0] + dx[i], aux[1] + dy[i]) == target_color.getRGB())
					stack.push(new Integer[] { aux[0] + dx[i], aux[1] + dy[i] });
			}

		}
	}
V

Gente desculpe pelo flood mas eu tenho certeza que alguem ai tem conehcimento e pode me ajudar neste probleminha, eu peço por favor que me ajude a resovler este problema e agradeço muito.

V

Up, please me ajudem… ‘-’

E

Não tenho a menor idéia.

Talvez o famoso livro do Michael Abrash (que não li inteiro) possa lhe dar alguma pista

C

Dando uma olhada rapida no seu codigo, percebi que voce esta passando pelo mesmo ponto varias vezes, que tal marcar os pontos
que voce ja passou para nao passar por eles novamente? Vai diminuir sua pilha de chamadas na funcao recursiva, e pode ser que melhore seu
algoritmo iterativo…

V

OMG…
Será que o ViniGodoy que ja me salvou varias vezes não poderia me salvar novamente ?

Obs: Ele não passa varias vezes pelo mesmo ponto não, o que acontece é que a cada ponto que ele insere na pilha, ele verificar os outros quatro ( >, < , /\ e / ).

Criado 25 de outubro de 2011
Ultima resposta 3 de nov. de 2011
Respostas 6
Participantes 3