Mudar cores em Imagem

38 respostas
L

Olá, galera!
Implementei um JPanel para visualizar a imagem de um boné, no formato .png…
O problema é que preciso modificar as cores de cada parte do boné, conforme o usuário for definindo…
Tipo, o usuário define a cor da toca do boné de Vermelho e então o bonezinho desenhado no JPanel fica com a toca em Vermelho… O usuário define a cor da toca para Azul e no mesmo desenho é pintada a aba em Azul, e assim por diante…
Pensei em criar vários desenhos de bonés, um para cada cor disponível e para cada parte que poderá ser modificada a cor, deixando as outras partes transparentes para então adicionar a imagem com a cor correta ao JPanel em cima da(s) outra(s) já definida(s), formando assim, ao final, o boné com várias imagens definindo as cores e o modelo… Mas, da forma que eu pinto a imagem no JPanel não consigo colocar uma por cima da outra…
Pensei também em criar isso em Flash para que eu pudesse gerar a imagem e guarda-la no banco, porém não imagino como vou guardar também as informações sobre os atributos definidos separados nos outros campos do banco de dados e nem como integrar isso ao swing…
E então pensei em Pintar apenas os pixels da região que estiver modificando a cor (seria a melhor opção para mim, porque não precisaria ficar desenhando centenas de imagens com todas as possibilidades de cores e modelos requeridos pelo usuário final)…
Mas eu não sei como fazer isso!
Alguém sabe como pintar uma determinada área da imagem (tipo BufferedImage) com as cores que eu quiser???
Se sim, sabe também se tem como definir a área respeitando exatamente os limites das partes do boné?
E ainda, alguém sabe outras formas para solucionar o meu problema?

Aguardo respostas.
Grato.

38 Respostas

V

O ideal é criar várias imagens, uma para cada parte do boné, e então junta-las.

Você cria uma série de imagens de abas, com fundo transparente, uma de cada cor.
Depois cria uma série de imagens da parte de cima do boné, com fundo transparente.

E então, monta uma bufferedImage que nada mais é do que as duas combinadas. Essa imagem final você exibe no seu painel.

V

Há ainda uma forma de mudar para qualquer cor.

Ainda com 2 imagens separadas:

Crie uma imagem da parte de cima do boné, mas ponha a cor dele com uma cor conhecida, como verde (0,255,0). Certifique-se que só a área que será pintada tem essa cor.
Faça o mesmo para aba.

Essas imagens serão sua matriz.

Faça um método que, dado uma imagem, uma cor de origem e uma cor de destino, substitua todas as ocorrências da cor de origem pela cor de destino. Assim você pode pintar as áreas verdes da cor que quiser. Para isso, você vai ter que percorrer a imagem original com um raster:
http://javaboutique.internet.com/tutorials/rasters/
http://javaboutique.internet.com/tutorials/rasters2/

Finalmente, aplique essa função tanto para a aba, quanto para o boné em si. Depois junte as duas imagens numa só e exiba para seu usuário. :wink:

L

Aí, brother…
Sabia que iria me ajudar, rsrsrsr… Agradeço muito!

ViniGodoy disse: “O ideal é criar várias imagens, uma para cada parte do boné, e então junta-las.
Você cria uma série de imagens de abas, com fundo transparente, uma de cada cor.
Depois cria uma série de imagens da parte de cima do boné, com fundo transparente.
E então, monta uma bufferedImage que nada mais é do que as duas combinadas. Essa imagem final você exibe no seu painel.”

Estive calculando por alto quantas imagens eu teria que criar para satisfazer todas as possibilidades que deveriam ser cedidas com essa forma de implementação e o resultado é estonteante! Isso, porque tenho que dar a possibilidade de modificar as cores de cada gomo que formam a toca do boné, do botão que fica na parte superior, da parte superior da aba, bem como da inferior, do sutache da aba (quando tiver), da cor da fivela (para cada modelo de fivela), da cor do suador; além de ter que mostrar o bonezinho em 5 ângulos diferentes para todos os modelos, respeitando todas as cores definidas! Assim, dá pra imaginar a quantidade de imagens que teria que criar com cada cor…

ViniGodoy disse: Faça um método que, dado uma imagem, uma cor de origem e uma cor de destino, substitua todas as ocorrências da cor de origem pela cor de destino. Assim você pode pintar as áreas verdes da cor que quiser. Para isso, você vai ter que percorrer a imagem original com um raster(…)
Finalmente, aplique essa função tanto para a aba, quanto para o boné em si. Depois junte as duas imagens numa só e exiba para seu usuário.

Essa seria, pelo meu ver, a solução mais viável! Assim eu poderia criar um método que aceite qualquer cor RGB obtida por um JColorChoose, por exemplo, sem me limitar a uma determinada lista de imagens, e sem a trabalheira de ter que criar esse tanto de imagens… Seria perfeito! Eu poderia atribuir cores mais “singulares” para cada componente do boné e reservá-las, utilizando-as para todos os ângulos; assim eu teria que criar apenas uma imagem para cada ângulo de visão e para cada modelo, e apenas modificar as cores reservadas de origem pelas de destino que o usário selecionar através do JColorChooser, criando uma BufferedImage com as cores reservadas e modificando essa bufferedImage com as cores selecionadas… Não é mesmo? Mas eu não entendi como trabalhar com raster (apanho muito por ser iniciante); não conseguir visualizar como vou pegar a cor de referência e substituir pela nova cor…
Você sabe mexer com raster? Pode me dar uma força???

V

Posso sim, não é tão difícil quanto parece. Basicamente é só usar os gets e sets que ele fornece.
Leia os tutoriais ali em cima e qualquer dúvida posta aqui.

L

Então, brother…
Sei que parece apelação, mas eu não consegui usar esses geters e seters para o que preciso…
Tentei assim:

int red, green, blue; WritableRaster raster = img.getRaster(); int pixels[] = new int[4]; raster.getPixels(0, 0, img.getWidth(), img.getHeight(), pixels); red = pixels[0]; green = pixels[1]; blue = pixels[2]; System.out.println("R: "+red+" G: "+green+" B: "+blue);
Mas dá erro no método getPixels()…
Como pode ver, não sakei muito isso não…
Como eu vou fazer para comparar as cores dos pixels da imagem com uma determinada cor???
E como vou mudar essa cor?

L

Eu lí os tutorias que me passou, mas não consegui extrair direito como vou fazer isso…
Helpe-me, please!!!

V

Que erro dá?

V

Use o método sem a altura e a largura da imagem.

Caso contrário, você estará tentando pegar os dados de todos os pixels da imagem inteira… o que exige um array gigantesco. É mais fácil e mais prático trabalhar pixel a pixel.

L

Brother… Não tinha visto suas últimas dicas, mas fiz exatamente o que você disse (eu acho) usando Raster ao invés de WritableRaster, depois de ler com mais detalhes os tutoriais… Bom, consegui reconhecer as cores da imagem, e até comparar, porém não consegui mudar essas cores para a BufferedImage…
Dê uma olhada no que fiz e diz se está certo…

int red, green, blue; Raster raster = img.getRaster(); int pixels[] = new int[5]; raster2.getPixel(0, 0, pixels); for (int i = 0; i < img.getWidth(); i++) { for (int ii = 0; ii < img.getHeight(); ii++) { raster.getPixel(i, ii, pixels); red = pixels[0]; green = pixels[1]; blue = pixels[2]; System.out.println("R: "+red+" G: "+green+" B: "+blue); if (pixels[0] == 255 && pixels[1] == 255 && pixels[2] == 255) { img.setRGB(50, 100, 150, 0, pixels, i, ii); } } }
Estou usando setRGB() para atribuir as cores mas não estou conseguindo mudar a cor…
Na saída no terminal consigo visualizar as cores dos pixels como implementei com System.out.println(), mas a cor não muda e não acontece nada, nenhum erro, e a velocidade está bem lenta…
Como vou mudar as cores?
Sabe me dizer?

V

O system.out deve estar deixando lento.

Depois de alterar a imagem, você chamou o invalidate no painel para ele repinta-la?

L

Fera, acho que a saída com System.out.println() não tem nada haver não… Creio que o problema está no método setRGB da classe BufferedImage, porque quando desabilito essa linha o processamento é quase instantâneo… Não estou sabendo usar esse método… Como pôde perceber, varri a imagem inteira para comparar os pixels, mas não estou conseguindo mudar a cor na BufferedImage…
Faz ideia do que estou fazendo de errado e de como deve ser???
Acho que até aqui já foi um grande avanço, mas não posso desistir…
Aguardo…

L

Ah, e tudo isso eu faço antes de pintar a imagem no JPanel…

img = ImageIO.read(new File(fc.getSelectedFile().getAbsolutePath())); Raster raster = img.getRaster(); int pixels[] = new int[5]; for (int i = 0; i < img.getWidth(); i++) { for (int ii = 0; ii < img.getHeight(); ii++) { raster.getPixel(i, ii, pixels); if (pixels[0] == 255 && pixels[1] == 255 && pixels[2] == 255) { img.setRGB(50, 100, 150); } } } if (quadroImagem == null) quadroImagem = new ImagePanel(img); quadroImagem.setImage(img); painelImagem.add(quadroImagem); painelImagem.repaint(); painelImagem.validate();

V

Você deve usar o método setPixel do Raster, não o setRGB do BufferedImage.
Mas o caminho é esse mesmo.

L

Então, nesse caso eu crio um WritableRaster ao invés de Raster, porque o Raster não me permite o método setPixel()… Mas quais informações eu devo passar como parâmetros para o método… Sim, porque ví na doc que é (X, Y, Largura, Altura, arrayRGB, Offset, scansize), mas não sei o que é esse Offset, nem esse scansize…
O que é?
Como eu completo esse código?

L

Então, esses parametros que mencionei eram da BufferedImage, mas do Raster é parecido…
Fiz assim, mas sem sucesso…

img = ImageIO.read(new File(fc.getSelectedFile().getAbsolutePath())); WritableRaster r = img.getRaster(); int pixels[] = new int[5]; for (int i = 0; i < img.getWidth(); i++) { for (int ii = 0; ii < img.getHeight(); ii++) { r.getPixel(i, ii, pixels); if (pixels[0] == 255 && pixels[1] == 255 && pixels[2] == 255) { r.setPixels(i, ii, img.getWidth(), img.getHeight(), pixels); img.setData(r); } } }O que pode estar errado:?

L

Hehehehehe…
Conseguiiiiiiiiiiiiii!!!
Mais uma vez você me ajudou muito ViniGodoy!!! Tenho aprendido muito com as suas dicas, mesmo as que vejo nos post’s de outos colegas onde você ajuda! Valeu mesmo, mais uma vez!
Como você disse no início, não é tão dificil como parece, e bastou dar umas lidas nas doc’s, orientando-me pelas suas dicas…
Segue como eu fiz…

// obtenho uma BufferedImage de um arquivo de imagem... BufferedImage img = ImageIO.read(new File(fc.getSelectedFile().getAbsolutePath())); // capturo o Raster da imagem num objeto do tipo WritableRaster (que permite alteração do Raster)... WritableRaster r = img.getRaster(); // crio um vetor que conterá os pixels varridos pelo Raster... int pixels[] = new int[img.getWidth * img.getHeight]; // calculo a matriz de pixels da imagem com base na largura x altura... for (int x = 0; x < img.getWidth(); x++) { for (int y = 0; y < img.getHeight(); y++) { // gravo os pixels do eixo x,y no vetor... r.getPixel(x, y, pixels); // comparo os pixels desse eixo com as cores RGB que eu quiser substituir... if (pixels[0] == 255 && pixels[1] == 0 && pixels[2] == 0) { // substituo os cores RGB da comparação por outras que eu quiser... pixels[0] = 150; pixels[1] = 100; pixels[2] = 50; // escrevo no WritableRaster novamente a matriz de pixels desse eixo... r.setPixel(x, y, pixels); } } } // e, por fim, atualizo a imagem com o Raster modificado... img.setData(r);
Note que se você colocar essa última linha dentro do laço ‘for’, o processamento será bem lento, porque a imagem será atualizada eixo a eixo…
Funcionou como uma luva! Porém, quando se modifica um tipo de imagem com compressão, como PNG (apesar de ser menos), JPG, GIF, por exemplo, é possível que fique alguns pixelsinhos nas bordas da área pintada com a cor antiga, porque essa borda apresenta uma pequena distorção nas cores RGB, não entendo direito; comigo foi assim; mas nada que não se possa dar um jeito, rsrsrs…
Um abraço! Espero que a solução dessa problemática venha ajudar alguém!
E, mais uma vez, obrigado, mestre ViniGodoy!

V

É verdade. Isso por que os algoritmos de lossy compression, como jpg, gif e mp3, descartam parte dos dados que, a princípio, não seriam perceptíveis aos seres humanos. Isso permite obter maiores taxas de compressão.

Do contrário, os algoritmos de compressão lossless não sofrem esse problema. Isso inclui o LZW, o png e o tiff.

Outra coisa que pode estar acontecendo é que sua ferramenta de desenho (gimp, corel, sei lá) deve estar suavizando a borda durante a exportação. Ela faz isso misturando parte dos pixels da borda com a cor do fundo. Isso dá um efeito visual muito melhor e várias ferramentas fazem isso por padrão. Entretanto, isso confunde o software. Veja se não existe a opção de não suavizar bordas na ferramenta e use-a.

S

Primeiramente, olá a todos :smiley:
Sou novo no forum e gostei muito daqui!
Me desculpem por reviver esse topico mas estou com um problema que provavelmente posso resolver de forma semelhante ao que o Linkel resolveu o dele…

Meu problema é o seguinte, ao carregar uma imagem na tela eu gostaria de dar uma opção ao usuário de mudar a cor da imagem, ele poderá fazer isso arrastando um JSlider (não lembro se é esse mesmo o componente) fazendo com que a imagem vá mudando de cor conforme ele vai movendo a barrinha

Eu pensei em fazer semelhante ao que o Linkel fez… mas não sei como eu faria para varrer completamente a imagem e mudar todas as cores por igual.

Será que poderiam me ajudar com esse problema? Realmente não tenho a mínima idéia de como fazer isso :cry:

J

Sairon:
Primeiramente, olá a todos :smiley:
Sou novo no forum e gostei muito daqui!
Me desculpem por reviver esse topico mas estou com um problema que provavelmente posso resolver de forma semelhante ao que o Linkel resolveu o dele…

Meu problema é o seguinte, ao carregar uma imagem na tela eu gostaria de dar uma opção ao usuário de mudar a cor da imagem, ele poderá fazer isso arrastando um JSlider (não lembro se é esse mesmo o componente) fazendo com que a imagem vá mudando de cor conforme ele vai movendo a barrinha

Eu pensei em fazer semelhante ao que o Linkel fez… mas não sei como eu faria para varrer completamente a imagem e mudar todas as cores por igual.

Será que poderiam me ajudar com esse problema? Realmente não tenho a mínima idéia de como fazer isso :cry:

Você precisa varrer a imagem com um laço na altura e largura, porque a imagem é uma matriz de bytes.
usando o código acima, que o vini godoy mostrou:

pixels[0] é o canal vermelho, pixels[1] é o verde, e pixels[2] é o azul.

todos eles tem a capacidade de um byte, ou seja, sua imagem possui 24bits/cor. Em java, esses valores podem varias de -128 a 127.

Pode usar 3 sliders e passar os respectivos valores para os bytes, assim você estará implementando um mecanismo de matização, e dependendo dos valores, vai conseguir a tonalidade que quiser.

V

Você só quer “avermelhar” (por exemplo) a imagem toda?

Veja esse pdf, na página 54, o método drawRedderImage:

S

Julio: Então cara, eu nunca tentei fazer esse tipo de coisa antes Oo. Dexa eu ver se entendi, simplesmente mudando os valores de pixel[0], pixel [1] e pixel[2] vai mudar as cores vermelha, verde e azul de toda a imagem? Ou eu teria que varrer a imagem inteira como você falou pra mudar pixel por pixel? Essa parte eu não entendi muito bem como faz olhando os códigos postados aqui no topico :frowning:

Vini: Então cara, eu queria que fosse mais ou menos igual quando tem uma imagem no photoshop, ae ao apertar crtl+u aparece uma opção para mudar o Hue, a mudança que ocorre ao rolar a barra, é a mesma que eu queria fazer no meu aplicativo.
Já mecheu com JavaFX? Seria tipo a função HUE de lá, eu tentei até importar essa função para o Java normal mas não consegui :cry:
Mas vo dah uma olhada no arquivo pdf que você postou ^^

J

Sairon:
Julio: Então cara, eu nunca tentei fazer esse tipo de coisa antes Oo. Dexa eu ver se entendi, simplesmente mudando os valores de pixel[0], pixel [1] e pixel[2] vai mudar as cores vermelha, verde e azul de toda a imagem? Ou eu teria que varrer a imagem inteira como você falou pra mudar pixel por pixel? Essa parte eu não entendi muito bem como faz olhando os códigos postados aqui no topico :frowning:

Vini: Então cara, eu queria que fosse mais ou menos igual quando tem uma imagem no photoshop, ae ao apertar crtl+u aparece uma opção para mudar o Hue, a mudança que ocorre ao rolar a barra, é a mesma que eu queria fazer no meu aplicativo.
Já mecheu com JavaFX? Seria tipo a função HUE de lá, eu tentei até importar essa função para o Java normal mas não consegui :cry:
Mas vo dah uma olhada no arquivo pdf que você postou ^^

É justamente isso… hue é o ajuste de matiz. Mudando os valores das bandas vermelha, verde e azul, você fará um ajuste de matiz.

Mas você tem que mapear toda a imagem conforme o código acima. Se quiser mudar somente pixels de uma determinada cor, é simples identificá-lo:

Para vermelho:

if(pixels[0]==127 && pixels[1] = -127 && pixels[1] = -127)

Isso se refere a um pixel vermelho.

Lembre que a imagem que voc~e está processandop possui 3 bandas de cor, ou seja 3 bytes, 24bit color. Imagens com formato de pixel diferente serão processadas de maneira diferente.

Só verifique se pixels[] é um inteiro ou um byte. Se for inteiro use um intervalo de 0 - 255, se for byte faça como acima.

E

faça isso.:

if (img.getRGB(x, y) == Color.red.getRGB()) {
                  
                }
S

Gente… agradeço muito por tentarem me ajudar ^^
mas to com um grande problema… a imagem que quero mudar a cor é um icone… como faço para converter ela e poder mudar a cor da imagem?

O setRGB é do BufferedImage … e soh consigo converter ela para Graphic
Então não sei como eu poderia usar o método de mudar o RGB da imagem sendo que não é da classe icon Oo … e não consigo converter ela para outro tipo de imagem sem ser Graphic

Alguém sabe como posso fazer isso?
Eu uso o netbeans… se alguém puder me mandar um exemplo de um aplicativo que faz isso… eu seria muito grato…
Mas acho que isso jah é pedir muito … se soh me falarem como resolver o problema do tipo de imagem acho que consigo solucionar o meu problema de mudar a cor da imagem

V

Como assim? Como você carregou a imagem?

Graphic não é uma imagem, Graphics representa um contexto gráfico.

J

Sairon:
Gente… agradeço muito por tentarem me ajudar ^^
mas to com um grande problema… a imagem que quero mudar a cor é um icone… como faço para converter ela e poder mudar a cor da imagem?

O setRGB é do BufferedImage … e soh consigo converter ela para Graphic
Então não sei como eu poderia usar o método de mudar o RGB da imagem sendo que não é da classe icon Oo … e não consigo converter ela para outro tipo de imagem sem ser Graphic

Alguém sabe como posso fazer isso?
Eu uso o netbeans… se alguém puder me mandar um exemplo de um aplicativo que faz isso… eu seria muito grato…
Mas acho que isso jah é pedir muito … se soh me falarem como resolver o problema do tipo de imagem acho que consigo solucionar o meu problema de mudar a cor da imagem

Eu não entendi direito. A imagem que você carregou é uma classe Icon? Porque não carrega para uma BufferedImage?:

BufferedImage image = ImageIO.read(...);
E
public String pintar(String color)
    {


        // obtenho uma BufferedImage de um arquivo de imagem...
        BufferedImage img = null;
        try {
             img = ImageIO.read(new File(url.getFile()));//seu arquivo
         
        } catch (IOException ex) {
          //  System.out.println("Erro 1.: "+ex);
            System.out.println("Erro 1.: "+ex);
        }

        // capturo o Raster da imagem num objeto do tipo WritableRaster (que permite alteração do Raster)...
        WritableRaster r = img.getRaster();

        //erro no (Degradê)
        Color color1 = new Color(253, 253, 253);
        Color color2 = new Color(254, 254, 254);
        Color color3 = new Color(244, 244, 244);
        Color color4 = new Color(228, 228, 228);
        Color color5 = new Color(208, 208, 208);
        Color color6 = new Color(227, 227, 227);
        Color color7 = new Color(232, 232, 232);
        Color color8 = new Color(234, 234, 234);
        Color color9 = new Color(214, 214, 214);

        Color color10 = new Color(223, 223, 223);

        Color color16 = new Color(198, 198, 198);
        Color color11 = new Color(243, 243, 243);
        Color color12 = new Color(209, 209, 209);
        Color color13 = new Color(187, 187, 187);
        Color color14 = new Color(211, 211, 211);
        Color color15 = new Color(200, 200, 200);
        //

        Color corAlvo = Color.decode("#"+color);

        // crio um vetor que conterá os pixels varridos pelo Raster...
        int pixels[] = new int[img.getWidth() * img.getHeight()];

        // calculo a matriz de pixels da imagem com base na largura x altura...
        for (int x = 0; x < img.getWidth(); x++) {
            for (int y = 0; y < img.getHeight(); y++) {
                // gravo os pixels do eixo x,y no vetor...
                r.getPixel(x, y, pixels);
                // se a imagem for branca e com erros
                if (img.getRGB(x, y) == Color.WHITE.getRGB() || img.getRGB(x, y) == color1.getRGB() ||
                   img.getRGB(x, y) == color2.getRGB() || img.getRGB(x, y) == color3.getRGB() ||
                   img.getRGB(x, y) == color4.getRGB() || img.getRGB(x, y) == color5.getRGB() ||
                   img.getRGB(x, y) == color6.getRGB() || img.getRGB(x, y) == color7.getRGB() ||
                   img.getRGB(x, y) == color8.getRGB() || img.getRGB(x, y) == color9.getRGB() ||
                   img.getRGB(x, y) == color10.getRGB()|| img.getRGB(x, y) == color11.getRGB() ||
                   img.getRGB(x, y) == color12.getRGB() ||
                   img.getRGB(x, y) == color13.getRGB() ||
                   img.getRGB(x, y) == color14.getRGB() || img.getRGB(x, y) == color15.getRGB() ||
                   img.getRGB(x, y) == color16.getRGB() ) {
                    // substituo os cores RGB da comparação por outras que eu quiser...
                    pixels[0] = corAlvo.getRed();
                    pixels[1] = corAlvo.getGreen();
                    pixels[2] = corAlvo.getBlue();
                    // escrevo no WritableRaster novamente a matriz de pixels desse eixo...
                    r.setPixel(x, y, pixels);
                }
            }
        }
        // e, por fim, atualizo a imagem com o Raster modificado...
        img.setData(r);
        String figuraModi= "nova figura";
        try {
              ImageIO.write(img, "png", new File(figuraModi+".png"));
         
        } catch (IOException ex) {
               System.out.println("Erro 2.:"+ex);
        } catch (Exception ex) {
               System.out.println("Erro 2.1.:"+ex);
        }

        return figuraModi;

    }

veja se isso lhe serve

S

Vini: Então cara… eu to carrendo a imagem definindo ela como um icone de um Jlabel … e soh tem a opção de mudar essa imagem que é de tipo icone para java.awt.Image (eu falei graphic… mas falei errado foi mal) … mudar para bufferedimage eu não consigo :’(

Julio: Eu to exibindo várias imagens num painel definindo elas como icone de Jlabel … por isso elas estão no formato icone… e não consigo de jeito nenhum converter para bufferedimage

Elton: Então cara… ae entramos no problema que digo acima… a imagem que estou usando é do tipo icone não consigo converter ela para outro formato que não seja Image …

Se não tiverem entendendo o pq estou usando como icone de Jlabel as imagens… eu posso postar aqui como está o aplicativo que criei até agora para vcs verem o que estou fazendo ^^

J

Sairon:
Vini: Então cara… eu to carrendo a imagem definindo ela como um icone de um Jlabel … e soh tem a opção de mudar essa imagem que é de tipo icone para java.awt.Image (eu falei graphic… mas falei errado foi mal) … mudar para bufferedimage eu não consigo :’(

Julio: Eu to exibindo várias imagens num painel definindo elas como icone de Jlabel … por isso elas estão no formato icone… e não consigo de jeito nenhum converter para bufferedimage

Elton: Então cara… ae entramos no problema que digo acima… a imagem que estou usando é do tipo icone não consigo converter ela para outro formato que não seja Image …

Se não tiverem entendendo o pq estou usando como icone de Jlabel as imagens… eu posso postar aqui como está o aplicativo que criei até agora para vcs verem o que estou fazendo ^^

Mas porque você não carrega em um BufferedImage e depois cria o Icon a partir dele? Se o problema é ter a imagem como buffered image, isso resolve seu problema.

S

Mas como eu faria para o Bufferedimage receber uma imagem de tipo icone? E vice versa? O.o

D

Olá, sou iniciante em JAVA e estava precisando de um programa que troque os pixels de uma imagem jpeg de preto para branco, é o mesmo problema do Linkel, certo ?
Eu estou tentando rodar o programa dele, mas não estou conseguindo, deve ser conceitos básicos, mas não estou conseguindo, alguém poderia me ajudar ?

package trocarcorimagem;

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import javax.imageio.ImageIO;


public class TrocarCor1 
{
     public static void main(String[] args)
    {
    
        // obtenho uma BufferedImage de um arquivo de imagem...   
        BufferedImage img = ImageIO.read(new File(fc.getSelectedFile().getAbsolutePath()));
        
        // capturo o Raster da imagem num objeto do tipo WritableRaster (que permite alteração do Raster)...   
        WritableRaster r = img.getRaster();   
        // crio um vetor que conterá os pixels varridos pelo Raster...   
        int pixels[] = new int[img.getWidth * img.getHeight];   
        // calculo a matriz de pixels da imagem com base na largura x altura...   
            for (int x = 0; x < img.getWidth(); x++) 
            {   
                for (int y = 0; y < img.getHeight(); y++) 
                {   
                // gravo os pixels do eixo x,y no vetor...   
                r.getPixel(x, y, pixels);   
                // comparo os pixels desse eixo com as cores RGB que eu quiser substituir...   
                    if (pixels[0] == 255 && pixels[1] == 0 && pixels[2] == 0) 
                    {   
                    // substituo os cores RGB da comparação por outras que eu quiser...   
                    pixels[0] = 150; pixels[1] = 100; pixels[2] = 50;   
                    // escrevo no WritableRaster novamente a matriz de pixels desse eixo...   
                    r.setPixel(x, y, pixels);                      
                    }   
                }   
            }   
        // e, por fim, atualizo a imagem com o Raster modificado...   
        img.setData(r);      
     }    
}

Na linha 14, o File e o fc ficam sublinhados de vermelho, o que eu devo fazer ? A imagem esta no caminho C:/Documents and Settings/XP/Desktop/a.jepg
Na linha 19, o getWidth e o getHeight ficam sublinhados também...

Alguém me ajude, por favor...
Abracos...

V
  1. Você precisa ter certeza que os pixels pretos são mesmo pretos. Isso é, tem o R, G e B iguais a 0.
  2. Basta usar os métodos getRGB e setRGB.

for (int y = 0; y &lt; img.getHeight(); y++) for (int x = 0; x &lt; img.getWidth(); x++) { Color pixel = new Color(img.getRGB(x, y)); if (pixel.getRed() == 0 && pixel.getGreen() == 0 && pixel.getBlue() == 0) img.setRgb(new Color(255, 255, 255).getRGB()); } }

D

Então ViniGodoy, mas eu não estou nem conseguindo rodar esse programa...

A linha 14 eu consegui arrumar, agora sõ falta 1 erro.
O erro esta em:
Na linha 22, o getWidth e o getHeight ficam sublinhados, porque ?

Desculpe se são problemas muito triviais, mas sou iniciante e não estou conseguindo.
Se me der umas dicas eu vou tentando...

package trocarcorimagem;

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException; 

public class TrocarCor1 
{
     public static void main(String[] args)
    {
    
       try
       {
        // obtenho uma BufferedImage de um arquivo de imagem...       
        BufferedImage img = ImageIO.read(new File("C:/Documents and Settings/XP/Desktop/Teste OCR/a.jpg"));
        
        // capturo o Raster da imagem num objeto do tipo WritableRaster (que permite alteração do Raster)...   
        WritableRaster r = img.getRaster();   
        // crio um vetor que conterá os pixels varridos pelo Raster...   
        int pixels[] = new int[img.getWidth * img.getHeight];   
        // calculo a matriz de pixels da imagem com base na largura x altura...   
            for (int x = 0; x < img.getWidth(); x++) 
            {   
                for (int y = 0; y < img.getHeight(); y++) 
                {   
                // gravo os pixels do eixo x,y no vetor...   
                r.getPixel(x, y, pixels);   
                // comparo os pixels desse eixo com as cores RGB que eu quiser substituir...   
                    if (pixels[0] == 255 && pixels[1] == 0 && pixels[2] == 0) 
                    {   
                    // substituo os cores RGB da comparação por outras que eu quiser...   
                    pixels[0] = 150; pixels[1] = 100; pixels[2] = 50;   
                    // escrevo no WritableRaster novamente a matriz de pixels desse eixo...   
                    r.setPixel(x, y, pixels);                      
                    }   
                }   
            }   
        // e, por fim, atualizo a imagem com o Raster modificado...   
        img.setData(r);   
        }
        catch (IOException e)
             {
             e.printStackTrace();
             }
     }    
}
V
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;

public class TrocarCor1 {
	public static void main(String[] args) throws IOException {
		// Abre a tela para escolher a imagem do disco
		JFileChooser fc = new JFileChooser();
		if (fc.showOpenDialog(null) != JFileChooser.APPROVE_OPTION)
			return;

		// Lê a imagem
		BufferedImage img = ImageIO.read(fc.getSelectedFile());

		// Altera os pixels
		for (int y = 0; y < img.getHeight(); y++)
			for (int x = 0; x < img.getWidth(); x++) {
				Color color = new Color(img.getRGB(x, y));
				if (color.equals(Color.BLACK)) {
					img.setRGB(x, y, Color.WHITE.getRGB());
				}
			}
		// Grava a saída no arquivo output.png
		ImageIO.write(img, "png", new File("output.png"));
	}
}
D

Valeu VinyGodoy, era isso que eu queria…
Muito obrigado…
Abracoss

V

Muito menos complexo e bem mais óbvio do que vc imaginava, não? :slight_smile:

D

Sim =)…
Mas a cor não é preta, o que eu pensava ser preto é formado por várias outras cores…
Estou mapeando as cores para tentar resolver, mas agora acho que já consigo…
Valeu…
Abraco…

V

É só fazer o getRed() getG() e getB() menores que um determinado valor pequeno (10, por exemplo).

Outra possibilidade é transformar em escala de cinza, e então testar por aí. Preferencialmente trabalhar com HSI no lugar de RGB.

Criado 11 de julho de 2008
Ultima resposta 12 de mai. de 2011
Respostas 38
Participantes 6