Ajuda com BufferedImage

Eu preciso ler uma imagem em tons de cinza pra fazer um algoritmo de quadtree para um trabalho de PDI. Preciso pegar o tom de cinza de cada coordenada da imagem pra fazer uma comparação.
O professor disse pra usar essa classe mas não disse mais nada e eu já olhei na API mas estou perdido.
Alguém pode me ajudar?

Para carregar um BufferedImage:

BufferedImage bi = ImageIO.read(new File("C:/suaImagem.png"));

Para pegar o tom baseado na coordenada:

Color pixel = new Color(bi.getRGB(x,y)); int tom = pixel.getRed(); //Red, Green e Blue em uma imagem Grayscale são iguais

Se a imagem for colorida, você pode passa-la para tons de cinza através do cálculo da luminância. A forma mais simples desse cálculo é:

int tom = (pixel.getRed() + pixel.getGreen() + pixel.getBlue()) / 3;

Para mais informações sobre como trabalhar com imagens:

E como seria um metodo que passa a imagem pra escala de cinza? Teria 2 for aninhado?
Poderia por favor me mostrar como seria sua implementação?

Interessante. Pode me explicar esse trecho do codigo?

Graphics2D g2d = pretaEBranca.createGraphics(); g2d.drawImage(imagem, 0,0, null); g2d.dispose(); ImageIO.write(pretaEBranca, "png", new File("imagempb.png"));
Tem coisa aí que eu nunca vi antes.

http://www.pontov.com.br/site/java/48-java2d/93-uma-visao-rapida-sobre-o-java-2d
http://www.pontov.com.br/site/java/48-java2d/111-trabalhando-com-imagens

Vlw muito obrigado!

Eu to usando

private static BufferedImage toGrayscale(BufferedImage image){ Color cor; int i; for (int x = 0; x < image.getWidth(); x++) { for (int y = 0; y < image.getHeight(); y++) { cor = new Color(image.getRGB(x, y)); i = (cor.getRed()+cor.getGreen()+cor.getBlue())/3; image.setRGB(x, y, i); } } return image; }
Mas a imagem ta ficando em tons de azul O.o

Claro, pois vc com a fórmula só calculou o tom da iluminação. Para que ela fique em escala de cinza, esse mesmo tom deve ser usado para os valores de R, G e B:

private static BufferedImage toGrayscale(BufferedImage image){ for (int x = 0; x &lt; image.getWidth(); x++) { for (int y = 0; y &lt; image.getHeight(); y++) { Color cor = new Color(image.getRGB(x, y)); int i = (cor.getRed()+cor.getGreen()+cor.getBlue())/3; image.setRGB(x, y, new Color(i, i, i).getRGB()); } } return image; }

No caso de grayscale, é mais rápido usar a conversão do próprio Java:

private static BufferedImage toGrayscale(BufferedImage image) throws IOException { BufferedImage output = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY); Graphics2D g2d = output.createGraphics(); g2d.drawImage(image, 0, 0, null); g2d.dispose(); return output; }

Eu até tava usando mas me incomoda usar codigo que eu não faço ideia do que faz e esse eu tentei entender e não consegui.

Cara, agora o problema eh com esse codigo:

public static void pintarTeste(){ for (int x = 0; x < imagem.getWidth(); x++) { for (int y = 0; y < imagem.getHeight(); y++) { imagem.setRGB(x, y, Color.green.getRGB()); } } }

Depois de executa-lo a imagem aparece pra mim como toda cinza. To quase desistindo desse programa ja…

Como você criou a variável imagem? No construtor você usou o tipo TYPE_INT_ARGB?

Pq se a imagem for TYPE_BYTE_GRAY (como eu usei ali), o Java irá converter automaticamente as cores fornecidas em tons de cinza.

Vish. Como que eu faço então?
Por enquanto to usando o método que seta em tom de cinza pixel por pixel com a media do RGB.

Se sua imagem é mesmo colorida, então aquele código ali deveria funcionar sim.

Deveria deixar a imagem toda verde.

Não, realmente eu estava transformando ela em escala de cinza. Mas agora eu to deixando rgb e mandando com akele metodo de pixel por pixel mesmo.
Pior que ainda assim não estou conseguindo fazer funcionar essa bagaça. O negócio eh o seguinte, estou implementando um algoritmo de Quadtree.
Esse método tem que me retornar se o quadrante da imagem que estou analisando contém apenas pixels dentro de um intervalo que eu estabeleci (que me dará que é um objeto), se contem apenas pixels fora desse intervalo (que me dará que e só o fundo), ou se contem os dois pra eu quebrar novamente em 4 quadrantes e analisar recursivamente montando uma arvore de quatro filhos cada nó (daí o nome) onde as folhas contém só objeto ou só fundo.

public boolean AnalisaQuadrante() { int cor; boolean fundo = false; boolean objeto = false; /* * varre o quadrante analisando pixel a pixel se este se encontra no * intervalo de cor do objeto */ for (int x = quadrante.getX(); x < quadrante.getLargura(); x++) { for (int y = quadrante.getY(); y < quadrante.getAltura(); y++) { cor = new Color(Quadtree.imagem.getRGB(x, y)).getGreen();//lembrando que as cores sao todas iguais System.out.print(cor+": "); if (cor > Quadtree.getMin() && cor < Quadtree.getMax()) { objeto = true; System.out.println("pixel de objeto"); } else { fundo = true; System.out.println("pixel de fundo"); } } /* * Ao final de cada linha analisa se foram encontrados pixels de * fundo e de objeto. Se sim, já retorna false indicando que não eh folha */ System.out.println("Fim de linha"); if (fundo && objeto) { System.out.println("Heterogeneo detectado"); return false; } } System.out.println("Fim de Quadrante"); // se for um objeto, já pinta este quadrante if (objeto) { System.out.println("FOLHA OBJETO DETECTADO!!!"); this.quadrante.pintar(); } else { System.out.println("Folha fundo detectado."); } return true; }

O limiar que estou utilizando é de 0 até 250 e a imagem é

Quando eu executo ele, ele não me identifica nenhuma folha como objeto, tudo como fundo. Não sei mais o que fazer…