Ponto V!

Home Java Java 2D Trabalhando com Imagens
Vinícius Godoy de Mendonça
Trabalhando com ImagensImprimir
Escrito por Vinícius Godoy de Mendonça

Nos artigos passados, vimos como desenhar imagens através de comandos de pintura. Entretanto, geralmente, não é o programador que desenha imagens, e sim, um artista num software de pintura qualquer. Nesse artigo, vamos ver como trabalhar com essas imagens, gravadas em disco.

Carregando imagens

O primeiro passo para usar qualquer imagem, obviamente, é carrega-las do disco. O Java oferece duas maneiras de se fazer isso, através da carga indireta, assíncrona e através da carga direta, síncrona.

Carga assíncrona

Com a carga assíncrona, comandamos o Java para que carregue uma imagem. Uma thread secundária é disparada para realizar esse trabalho, fazendo com que o método de leitura retorne imediatamente. Não poderemos usar a imagem logo em seguida, pois ela pode não estar na memória. Para sabermos o momento em que ela foi completamente carregada, temos que registrar um ImageObserver, ou utilizar da interface MediaTracker. O código abaixo demonstra um exemplo:

//Disparamos a carga da imagem. O objeto Image representa a imagem sendo carregada.
//Esse método retorna imediatamente.
Image image = Toolkit.getDefaultTookit().getImage(fileName);
//Criamos um MediaTracker para aguardar a carga. O parâmetro this representa um componente, //que pode ser o frame ou o applet onde o tracker está. MediaTracker mt = new MediaTracker(this); //Registramos a imagem com id 0. mt.addImage(image, 0); //Esperamos ela carregar. Poderíamos registrar várias imagens, //e também chamar o método waitForAll(), para carregar todas. try { mt.waitForId(0); } catch (InterruptedException e) { }

Carga síncrona

Embora a carga assíncrona seja adequada para aplicações, sobretudo applets, ela não é adequada para jogos. Em quase 100% dos casos, iremos precisar ter certeza de que a imagem foi carregada, antes de exibi-la. Com a carga síncrona o java carregará uma imagem, e só retornará quando ela estiver integralmente carregada. Fazemos a carga síncrona através da classe ImageIO:

try {
   BufferedImage image = ImageIO.read(new File(fileName));
} catch (IOException e) {
}

Note que o tipo retornado agora é um BufferedImage, não simplesmente um Image. O BufferedImage é uma classe filha de Image que representa uma imagem carregada na memória. A grande diferença das duas é que o BufferedImage irá permitir a manipulação da imagem. Carregar imagens através da classe ImageIO é a forma recomendada pela Sun atualmente.

Desenhando a imagem

Você já viu nos artigos anteriores como trabalhar com a classe Graphics. Como você já deve ter deduzido, existem métodos por lá para desenhar a imagem. Uma das coisas mais interessantes, é que o Java não disponibiliza um, mas sim, dezenas de métodos para isso. Veremos dois dos mais importantes. Os outros, são derivações destes.

O primeiro, e mais simples, é quando queremos desenhar uma imagem num local específico da tela.

boolean Graphics.drawImage(Image img, 
                           int x, int y,
                           ImageObserver observer);

Simplesmente passamos a imagem, duas coordenadas e, opcionalmente, um ImageObserver. Essa interface é útil para quando usamos carga assíncrona, e não carregamos a imagem através do media tracker. O método draw() irá esperar até que a imagem esteja desenhada, para então disparar um evento nos avisando que a pintura terminou. Essa técnica é adequada em aplicações, onde esperar pela carga da imagem no momento da pintura não é um problema. Não é o caso dos jogos. Como já teremos carregado nossa imagem com um MediaTracker, ou teremos usado o ImageIO, podemos passar null nesse parâmetro.

O segundo método de pintura, permite-nos desenhar apenas uma parte da imagem:

boolean Graphics.drawImage(Image img,
                           int dstx1, int dsty1, int dstx2, int dsty2,
                           int srcx1, int srcy1, int srcx2, int srcy2,
                           ImageObserver observer);

Nesse método, fornecemos a imagem, 4 coordenadas no destino (dst) e 4 na origem (src). O Java irá pintar só a porção determinada por essas coordenadas, fazendo a escala para que ela encaixe no destino. Por exemplo, se as coordenadas de origem forem (0,0)-(10,10) e a de destino forem (0,0)-(25,25), a imagem será redimensionada. Esse método é útil para criarmos, por exemplo, uma única imagem com várias partes de uma animação, e desenharmos apenas uma parte por vez no programa.

Desenhando sobre uma imagem

Um dos recursos mais bacanas da API do Java 2D, é que é extremamente fácil desenhar sobre uma imagem. Todo BufferedImage é também uma área de pintura. Podemos criar um BufferedImage em branco e desenhar sobre ele, ou mesmo desenhar sobre uma imagem carregada. Para isso, usamos o método createGraphics(), que retorna um objeto do tipo Graphics2D. A partir daí, basta desenhar na imagem como faríamos na tela.

No artigo anterior, comentei que o desenhar diretamente no Java 2D, sobretudo quando se usa antialiasing e GradientPaint pode ser uma tarefa bastante custosa. Agora, e se fizéssemos esses comandos de desenho uma única vez, e guardássemos o resultado numa BufferedImage? Os desenhos seguintes seriam feitos diretamente através da imagem, sem envolver cálculos de antialising, escala, rotação, preenchimento ou texturas. De fato, fazer isso é possível, e até bastante fácil:

//Criamos uma imagem de 80x100 pixels
BufferedImage ghost = new BufferedImage(
 80, 100, BufferedImage.TYPE_INT_ARGB);

//Obtemos o contexto gráfico dessa imagem
Graphics2D g2d = ghost.createGraphics();

//Desenhamos nela o fantasma do artigo anterior :)
new Ghost().draw(g2d);

//Liberamos o contexto.
g2d.dispose();

Após esse código, poderíamos simplesmente desenhar a imagem definida na variável ghost, quantas vezes quiséssemos. Isso permite manter a qualidade do desenho ao mesmo tempo que mantemos a velocidade de pintura na hora do jogo propriamente dito.

Salvando a imagem no disco

O método ImageIO.write é responsável por salvar a imagem no disco. Devemos passar para o método a imagem a ser salva, o formato do arquivo e o nome. O Java se encarregará de fazer a conversão do formato da BufferedImage para o formato de saída, podendo haver perdas nesse processo. Uma imagem com transparência, por exemplo, poderá ficar com fundo branco se for gravada num formato que não suporte transparência. Da mesma forma, imagens do tipo JPG geralmente são geradas com uma taxa de compactação alta e podem apresentar distorções.

Gravar imagens no disco pode ser uma técnica interessante para criar caches, e evitar penalizar o jogador com operações caras como redimensionamento e desenho toda vez que o jogo é carregado. A assinatura do método é a seguinte:

static boolean ImageIO.write(RenderedImage im,
                             String formatName,
                             File output) throws IOException

A classe BufferedImage implementa a interface RenderedImage. O boolean retornado pelo método indica se um writer para aquele formato foi encontrado ou não. Para os formatos descritos abaixo, o retorno true é garantido. Outros formatos podem ser instalados através da APIs externas.

Formatos de imagem suportados

O Java suporta uma série de formatos de imagem. Abaixo, uma breve descrição dos principais:

  • Bitmaps (BMP): É o formato, de longe, mais rápido de ser carregado e pintado. Porém, não suporta transparência e por não conter compactação, gera arquivos de imagem de tamanho grande.
  • JPG: Possui compactação do tipo lossy, ou seja, pode haver perda de qualidade se a compactação for muito agressiva. Por outro lado, mesmo numa taxa baixa de compactação já apresenta um tamanho de arquivo consideravelmente menor que o bitmap. Também não suporta transparência.
  • GIF: Suporta transparência e vários tipos de compactação. Também suporta que várias imagens sejam gravadas no mesmo arquivo, e sejam exibidas na forma de animação em browsers.
  • PNG: Equivalente ao GIF, mas a compactação geralmente é sem perdas. Como é um formato livre, foi extremamente otimizado na API do Java, e é o formato com transparência recomendado pela Sun.

Concluindo

Nesse artigo, vimos de maneira bem prática e direta como carregar e manipular imagens em Java. Só com o que foi visto, já é possível desenhar qualquer cena do jogo. Sugiro que você tente fazer um programa que carregue algumas imagens, para exercitar o que foi visto.


Comentários (84)
  • Bruno Daniel Marinho  - Melhor artigo ^^
    avatar

    Muito legal o artigo gostei especialmente do metodo Graphics.drawImage sobre carregado para pintar apenas uma parte da imagen estou fazendo algums testes aqui com uma imagen so agente pode desenhar um cenario todo neh?

    SHow!

  • Vinícius Godoy de Mendonça
    avatar

    Sim. Apesar de que várias imagens são comumente usadas para dar o efeito de paralaxe (isto é, que o fundo mova-se mais lentamente em relação à frente).

  • Eduardo Skrepnek Tosin  - Excelente
    avatar

    Achei excelente seu artigo. Me sanou várias dúvidas quanto o carregamento de imagens por sprites.
    Gostaria de saber se tu tens como me ajudar com o flicker e doublebuffering no java, pois não entendi como ele realmente funciona num applet.

    Obrigado.

  • Vinícius Godoy de Mendonça  - Flickering e Buffer
    avatar

    O próximo artigo vai lidar com esse assunto. Você precisa de duas coisas para eliminar o flickering:

    a) Um game loop consistente;
    b) Double buffering.

    Por incrível que pareça, a maior parte dos programadores Java se perde no ponto a), não no b). Você já leu o artigo "animação baseada em tempo", aqui do portal? Ele pode te ajudar.

  • Thiago
    avatar

    Parabéns pelo artigo Vini! Ficou muito bom

  • seudito  - Modo assíncrono
    avatar

    Olá Vini,

    Achei interessante o artigo, parabéns.

    Você acredita ser possível utilizar o modo assíncrono para redimensionar imagens em Java, e em caso afirmativo, desta forma pode ser mais rápido?

    Estou mechendo em uma aplicação onde redimensiono as imagens carregando-as de forma síncrona, e então, lendo o artigo me surgiu esta dúvida. Obrigado!

  • Vinícius Godoy de Mendonça
    avatar

    Você só poderá redimensiona-las depois da imagem completamente carregada. Nesse caso, você deve usar o último parâmetro, que se refere ao image listener. Ele recebe uma notificação quando a carga da imagem está completa, e então, você faz o redimensionamento sob demanda.

  • Anônimo  - Informação
    avatar

    Bom dia Vinicius, achei interessante este seu arquivo.
    Sou iniciante e gostaria de saber se tenho como fazer um adm de templates em java.
    Nesta templates o adm poderá trocar as imagens de promoções da parte inicial do site.. teria como faer isto em java?

  • Vinícius Godoy de Mendonça
    avatar

    Tem sim. Esse portal é mais relacionado a jogos. Como sua dúvida é mais relacionada ao desenvolvimento de uma aplicação web, surgiro que a poste no GUJ.

  • Xilon
    avatar

    Amigo, não tem como voce colocar um exemplo completo, de desde carregar a imagem do disco(indicando até o diretorio q deve estar a imagem), colocá-la em um buffered image e depois desenhá-la na tela, que se eu copiar e colar o código ele funcione aqui direto.......estou desesperado......to a mais de 2 dias tentando criar uma janelinha com uma imagem dentro e não consigo....em todos os tutoriais que eu acho pela net me parecem incompletos e confusos......

  • Mateus  - Duas perguntas
    avatar

    Tem como eu rotacionar uma imagem ou espelha-la?

  • Vinícius Godoy de Mendonça
    avatar

    Tem sim. Para espelhar, basta fornecer os dados da imagem ao contrário (dizer que ela começa na largura e termina em 0).

    Para rotacionar, você precisa alterar a transformação do Graphics2D.
    Veja um exemplo neste post do GUJ.

    Lembre-se que o ângulo é em radianos. Se você quiser fornecer em graus, use o método Math.toRadians().

  • adailton  - carregar gif
    avatar

    cara tem como carregar uma imagem no java no formato gif ou algo assim?

  • Vinícius Godoy de Mendonça
    avatar

    Tem sim, é só seguir o que está escrito nesse artigo. ;)

  • Leandro
    avatar

    parabéns Vinícius, ja add a pagina nos favoritos...

    Tenho um JPanel com o layout GridLayout(2,5)
    e nesse tenho que adcionar até 10 imagens com tamanhos específicos,
    e em determinados momentos preciso trocar essas 10 imagens de 1 em 1 segundo (porém preciso mostrar as imagens)
    tenho aproximadamente umas 10.000 imagens qual é a melhor maneira de se fazer esse processo ?

    obs.: O JFrame fica em fullscreen.
    idéia semelhante: http://online.wsj.com/public/resources/documents/EndOfYearSlideshow-Co olIris.html

  • Vinícius Godoy de Mendonça
    avatar

    Eu implementaria meu próprio JPanel com essa capacidade, sem recorrer ao GridLayout. Basta usar os conceitos já apresentados aqui no portal (entenda bem o Java2D e o GameLoop)

  • Leandro  - re:
    avatar
    Vinícius Godoy de Mendonça Escreveu:
    Eu implementaria meu próprio JPanel com essa capacidade, sem recorrer ao GridLayout. Basta usar os conceitos já apresentados aqui no portal (entenda bem o Java2D e o GameLoop)
    Vinícius Godoy de Mendonça Escreveu:
    Eu implementaria meu próprio JPanel com essa capacidade, sem recorrer ao GridLayout. Basta usar os conceitos já apresentados aqui no portal (entenda bem o Java2D e o GameLoop)

    Poderia mostrar um exemplo ?

    Obrigado.

  • Vinícius Godoy de Mendonça
    avatar

    Esse exemplo não faz exatamente o que você quer, mas já roda o programa num loop:
    http://www.guj.com.br/java/128713-jframe-com-imagem-em-fade#1165351

  • Leandro
    avatar

    Valeu Vinícius

  • Davi  - IloveVINI
    avatar

    vinivnivnivni.. não é a primeira vez q vc me salva!
    bom trabalho!!

  • Vinícius Godoy de Mendonça
    avatar

    Valeu.

  • allan
    avatar

    Olá, olha digamos que eu tenha uma imagem que corresponde ao meu herói como é que eu faço para saber se ela colidiu com outra imagem que seria a do inimigo? Posso colocar a imagem dentro de um retângulo?

  • Vinícius Godoy de Mendonça
    avatar

    Use o método intersects da classe Rectangle2D. O rectangle irá representar o bouding box da imagem (se seu objeto for redondo, talvez seja melhor usar o Ellipse2D ao invés do Rectangle).

  • allan
    avatar

    como eu faço para saber se a imagem do inimigo colidiu com a imagem do inimigo?

  • Vinícius Godoy de Mendonça
    avatar

    Crie um Retangle2D com as coordenadas e dimensões da imagem do herói. Crie outro Rectangle2D com as coordenadas e dimensões da imagem do inimigo. E então use o método intersects nesses dois retângulos.

  • washington  - Redimensionar imagem
    avatar

    Preciso ajuda!!!
    Não estou conseguindo redimensionar a imagem em uma jlabel.
    consigo traze-la, mas fica com tamanho desproporcional à jlabel.
    segue o código abaixo.

    Obrigado;

    private void jb_foto1ActionPerformed(java.awt.event.ActionEvent evt) {

    try

    {
    JFileChooser busca_foto = new JFileChooser();
    busca_foto.setCurrentDirectory(new File("/pcio/imagens/";));
    busca_foto.setDialogTitle("Carregar imagem da OAEs";);
    busca_foto.showOpenDialog(this);
    String foto = ""+busca_foto.getSelectedFile().getName();
    tf_foto1.setText(foto);
    jlb_Foto1.setIcon(new ImageIcon("/pcio/imagens/"+tf_foto1.getText()));
    }
    catch(Exception erro)
    {
    JOptionPane.showMessageDialog(null,"Nao foi possível carregar a foto.";);
    }


    }

  • wilson  - Recuperar a imagem sobreposta
    avatar

    No item :Desenhando sobre uma imagem,
    no final, como eu faço pra recuperar esse g2d, preciso usá-lo, pra salvar no disco, por exemplo.

    //Liberamos o contexto.
    g2d.dispose();

  • Vinícius Godoy de Mendonça
    avatar

    O g2d é apenas a "caneta", não a imagem. O que você quer salvar está no BufferedImage, no caso do exemplo, ghost.

    Para salvar no disco, você faria isso após o dispose():
    ImageIO.write(ghost, "png", new File("C:\ghost.png";));

  • David Rocha  - Imagem sobre outra imagem
    avatar

    Cara, teria como eu carregar uma imagem na janela, ai carregar outra imagem por cima, e depois salvar o desenho que formou na janela?
    Por exemplo:
    -Carrego a imagem de um rosto.
    -Ai escolho a imagem de um óculos e posiciono nos olhos
    -Salvo a imagem do rosto com óculos em .png no disco.

    Como seria isso?

  • Vinícius Godoy de Mendonça
    avatar

    Sim, é perfeitamente possível.

    Como você viu, é possível desenhar uma imagem sobre outra, usando o Graphics2D.drawImage.

    Também é possível salvar esse conteúdo novamente, usando o ImageIO.write.

  • David Rocha  - Imagem sobre imagem
    avatar

    Maravilha!
    Mas ai, por exemplo, a imagem ficaria solta sobre a outra? Ou ela iria se "fundir" a outra?
    Eu poderia no caso carregar a imagem na posição correta dos olhos, e poder arrastar um pouquinho pra cima, ou pra baixo, redimensionar, etc?

  • Vinícius Godoy de Mendonça
    avatar

    A imagem final será fundida.

    Para fazer a interface gráfica, você até pode dar a "ilusão" de que uma imagem está "solta" sobre a outra. Mas no fundo, você terá as duas imagens originais e desenhará a imagem final várias vezes, a medida que o usuário move a imagem de cima sobre a de baixo.

  • Hugo Carvalho
    avatar

    a um programa cujo objetivo é gerar um conjunto de recortes produzidos a partir de
    uma imagem informada pelo usuário. Além da imagem, o usuário também irá informar a
    quantidade de linhas e colunas que serão utilizadas para obter os recortes. Para tal, faça
    uma pesquisa sobre as classes javax.imageio.ImageIO e java.awt.image.BufferedImage.
    Note que o programa deve produzir um novo arquivo para cada recorte gerado

    alguma dica ?!

  • Vinícius Godoy de Mendonça
    avatar

    Já tentou ler o javadoc das classes indicadas pelo seu professor? Você vai ver que o BufferedImage tem um método para desenhar parte da imagem. O resto da lógica é com você.

  • Douglas  - Manipulação de imagens com lentidão.
    avatar

    Tenho uma aplicação que usa bastante imagens, e é possível fazer drag and drop com elas para outros componentes. Porém, o problema está no processamento dessas imagens.
    Quando é adicionado imagens na biblioteca de imagens, elas são transformada em thumbnails, mas ficam "pesadas" deixando a aplicação lenta, mesma coisa acontece quando se pega o frame de um video para fazer seu thumbnails.
    E ainda, com essa imagens da biblioteca é possível arrastá-la para preencher um componente onde é exibida a imagem em tamanho maior o que deixa ainda pior a lentidão da ferramenta.
    Alguém sabe o que poderia ser?

    Obrigado.

  • Vinícius Godoy de Mendonça
    avatar

    Fica difícil sem ver seu código fonte.

    Em todo caso, use um profiler, pois ele é capaz de medir o desempenho do seu programa e identificar onde está o gargalo.

    O Java vem com um profiler, chamado Visual VM:
    http://visualvm.java.net/

    Se você estiver usando o Netbeans, ele também tem um profiler embutido:
    http://profiler.netbeans.org/

  • deyverson  - duvida sobre maquiagem digital
    avatar

    estou com duvida se teria como fazer o java reconhecer um olho ou uma boca e eu depois adicionar a eles uma cor diferenciada e etc? ou seja fazer tipo uma maquiagem da foto importada

  • Vinícius Godoy de Mendonça
    avatar

    Teria sim, mas não é uma tarefa trivial se for de forma automática. Você pode procurar por uma biblioteca chamada javacv, que é um binding para a biblioteca C++ chamada OpenCV.

  • Adriano dos Santos  - Trabalhos com 3D
    avatar

    Como eu faco pra utilizar imagens em 3D e ate animacoes???Da pra fazer isso????Tipo eu vou informar uma letra e ele me retorna uma imaggem em 3D.

  • Douglas  - Aplicação em Java para web
    avatar

    Oi Pessoal,

    Eu tenho uma aplicação em java inteira pronta já. Mas eu quero
    que ela funcione num browser. Ah melhor maneira para fazer isso
    é usando Java Applet ? O processo é simples ? Minha aplicação usa a API Java Swing, tem algum problema para transformar em um applet?

    Obrigado.

  • Vinícius Godoy de Mendonça
    avatar

    Se ela só precisar ser disparada pelo Browser, a maneira é via JNLP, como essa aqui: http://www.pontov.com.br/files/outros/vinigodoy/particles/particles.ht ml

    Isso é extremamente simples de fazer. Se precisar rodar dentro do browser, aí o ideal é fazer em applets. Já dá um pouco mais de trabalho, pois os painéis dos seus JFrames terão que ser abertos pelo JApplet. O idioma muda um pouco também, já que não é costume ter várias janelas em applets.

  • Douglas
    avatar

    Muito obrigado Vinícius por sua atenção,

    Parabéns pela sua constante colaboração aqui no portal.
    Eu vou então, inicialmente, usar JNLP, pois minha aplicação
    é um editor gráfico de aplicações pra TV Digital e possui muitas janelas, pelo que eu entendi, não vai ser uma tarefa trivial, vai precisar de um planejamento de como irá ser feita esta transformação para applet.

    Obrigado, novamente.

  • Ricardo  - JImagePanel com GIF
    avatar

    Olá,
    Eu uso o JImagePanel para fazer meus paineis com background, porém quando uso um gif a imagem fica estática. Poderia me ajudar com isso?

    Agradeço,
    Ricardo.

  • Douglas  - Duração de mídias com JMF
    avatar

    Oi Pessoal,
    eu estou usando JMF para obter a duração de uma mídia
    contínua ( áudio ou vídeo ), porém é retornado um valor
    incorreto. Segue meu código abaixo:

    Player player = Manager.createPlayer(getClass().getResource("mus.mp3";));
    Double implicitDur = player.getDuration().getSeconds();

    Valor retornado: implicitDur = 9.223372036854776E9

    Obrigado,
    Douglas.

  • Thiago  - Redimensionar imagens
    avatar

    Olá Vinícius,

    parabéns pelo artigo.

    Estou redimensionando várias imagens e salvando em disco.
    Gostaria de saber como fazer para liberar a memória após salvar a imagem em disco?
    Notei que quando faço o loop a utilização da memória aumenta e quando fecho a aplicação ela libera da memória.

    Abç

  • Vinícius Godoy
    avatar

    Você só precisa remover todas as referências da imagem. Isso vai liberar memória do heap da VM.

    Entretanto, a memória física que a VM ocupa vai provavelmente expandir um pouco, e essa memória só o java tem a capacidade de liberar. Ele não faz isso imediatamente, e não há comando para forçar essa liberação.

  • Thiago  -  Redimensionar imagens
    avatar

    Olá Vinícius,

    poderia me dar um código de exemplo de como poderei liberar memória do heap da VM?

    Obrigado.

  • Tania Silva  - Processamento de Imagem
    avatar

    Olá, sou iniciante em programação Java para processamento de imagens digitais e tenho duvidas sobre:

    WritableRaster imagem = metade.getRaster();

    onde está escrito imagem, posso dar qualquer outro nome?
    e o que seria onde está escrito metade?

    Esta linha de codigo está em um programa para redimensionar imagem pela metade. Tem algum exemplo onde eu possa entender melhor um codigo de redimensionamento?

    Quando executo esse codigo, não aparece minha imagem redimensionada, o que há de errado?

    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.awt.image.WritableRaster;
    import java.io.File;
    import java.io.IOException;
    import java.util.Scanner;
    import javax.imageio.ImageIO;
    import javax.swing.JFileChooser;
    public class Main {


    public static void main(String[] args) throws IOException {

    JFileChooser arquivo = new JFileChooser();
    arquivo.showOpenDialog(arquivo);
    String caminho = arquivo.getSelectedFile().getAbsolutePath();


    BufferedImage input = ImageIO.read(new File(caminho));

    BufferedImage im = new BufferedImage(input.getWidth(),input.getHeight(),BufferedImage.TYPE_BY TE_GRAY);


    Graphics2D g2d = im.createGraphics();

    g2d.drawImage(input,0,0,null);

    ImageIO.write(im,"PNG",new File("original.png";));

    WritableRaster NovoRaster = im.getRaster();


    Scanner sc = new Scanner(System.in);

    int altura = input.getHeight();
    int largura = input.getWidth();


    BufferedImage metade = new BufferedImage(input.getWidth(),input.getHeight(),BufferedImage.TYPE_BY TE_GRAY);

    WritableRaster imagem = metade.getRaster();

    largura = input.getWidth();
    altura = input.getHeight();


    for(int h = 0; h < altura;h = h+4)
    {
    for(int w = 0; w < largura;w = w+4)
    {
    imagem.setSample(w/4, h/4, 0, NovoRaster.getSample(w, h, 0));
    }
    }

    g2d = metade.createGraphics();

    g2d.drawImage(input,0,0,null);


    ImageIO.write(metade,"PNG",new File("metade.png";));


    }


    }

  • ViniGodoy
    avatar

    Oi Tania, esse é um site sobre games, e nosso espaço é dedicado à duvidas sobre os artigos. Para outras dúvidas de Java, por favor, envie a mensagem no GUJ: http://www.guj.com.br

    Desde já, recomendo que você visite esse tópico:
    http://www.guj.com.br/java/244860-roadmap-processamento-de-imagens

  • Tania  - Ah sim
    avatar

    Verdade, obrigada :) Conheci hoje seu portal, parece ser ótimo, visitarei sempre, pois estou trabalhando paralelamente com desenvolvimento de jogos também!

    Obrigada!

  • igor carneiro  - Comparando Cartao resposta
    avatar

    Muito bom mesmo essa artigo... Parabens!!!
    Será que é possivel ???
    Estou pretendendo comparar "cartoes resposta" de alunos com o origonal.
    Quero scanear os cartoes dos alunos e contabilizar o numero de questoes acertadas.
    Levando em consideracao tb, se na hora de scanear o "cartao resposta" fica um pouco "torto"

    Obrigado pela ajuda.

  • Vinicius Godoy
    avatar

    Para esse caso, é bem mais fácil você pegar aplicações prontas, que transformam os cartões em arquivos de textos já escaneados. Uma delas é o capturer pro, mas deve haver mais baratas para o caso de cartões resposta.

    Para fazer isso na mão, você teria que estudar bastante sobre visão computacional. Procure por "template matching" para saber como identificar as questões marcadas e por algoritmos de detecção de linhas (como a transformada de Hough) para saber como desentortar a imagem. Seria bom ver também algum algoritmo de limiarização, para simplificar a imagem. Mas prepare-se para uns bons meses de estudo.

  • igor carneiro
    avatar

    Vinicius,
    Não tenho a intensao de identificar letras e numero; e sim somente compara as duas imagens (gabarito oficial X gabarito aluno)... e interpretar a questao da linha 1 (1ª Questao) esta igual a linha da outra imagem.

  • ViniGodoy
    avatar

    Eu entendi exatamente o seu problema, e tudo que eu falei ainda vale.

  • Anônimo  - re:
    avatar
    ViniGodoy Escreveu:
    Eu entendi exatamente o seu problema, e tudo que eu falei ainda vale.
    ViniGodoy Escreveu:
    Eu entendi exatamente o seu problema, e tudo que eu falei ainda vale.

    Vinicius,

    Como eu identifico um retângulo, com tamanho pré-determinado, dentro de uma imagem ????

  • Thiago  - Lentidão ao redimensionar
    avatar

    Olá Vinicius,

    criei um frame para rodar no windows e com o mesmo código um applet para rodar pelo browser. Me corrija se estiver errado.

    Por que quando rodo a aplicação pelo windows desktop ela é bem mais rápida do que quando rodo o applet pelo browser?

    O que preciso fazer para melhorar a velocidade para executar via browser?

    Obrigado por sua ajuda.

  • igor carneiro  - re:
    avatar
    igor carneiro Escreveu:
    Vinicius,
    Não tenho a intensao de identificar letras e numero; e sim somente compara as duas imagens (gabarito oficial X gabarito aluno)... e interpretar a questao da linha 1 (1ª Questao) esta igual a linha da outra imagem.

    Acredito que terei também que separar a imagen em regiões, caso elas estejam separadas de 10 em 10.

  • ViniGodoy
    avatar

    Use jnlp para que o applet tenha acesso a placa de vídeo.

  • thiago  - Japplet + html
    avatar

    Vinicius,

    como faço para minha applet pegar um arquivo na minha máquina local e adicionar como anexo em minha aplicação php ou html?
    Sem que eu tenha que clica no botão anexar e localizar o arquivo.

    Obrigado.

  • Erik Guilherme Tartaglia  - Instrução createCompatibleImage(...)
    avatar

    Muito bom seu site, serve de um bom norteio para quem esta começando (meu caso :D).

    Só me gerou uma pequena dúvida em relação a outros tutoriais que tenho visto. Após ler os artigos aqui no site comecei o livro Killer game programming in java, no livro é citado a necessidade da criação e uma imagem compatível a partir do GraphicsConfiguration.createCompatibleImage(...), apesar de no próprio livro o autor citar que a partir do java 5 isto não era mais necessário todos os tutoriais que encontrei até o momento apresentam esta instrução (exceto este). Essa instrução ainda apresenta alguma vantagem?

  • ViniGodoy
    avatar

    Ainda é desejável, mas o impacto não é tão significativo quanto era antes do Java 5, pois agora essa diferença é tratada pela placa de vídeo.

  • Paulo  - desenhando várias imagens
    avatar

    Muito bom o tópico! :)
    Mas além disso tenho outro motivo para estar aqui, na criação de jogo 2D por exemplo, temos o uso de muitas imagens, desenhos de mapas e todo o processamento da lógica, comecei a criar um jogo mas estou com uma dúvida sobre isso, porque quando carrego muitas imagens na tela o jogo fica extremamente lento, cada objeto tem seu própio método de desenho, os monstros são desenhados pela fase, o que eu pensei foi criar uma espécie de escalonador de desenhos, um ponteiro global para essa classe é usada para fazer os desenhos do jogo, ele poderia disparar threads quando tempo de desenhos estiver muito alto e eu poderia facilmente alterar a ordem de desenho, mas não sei direito, antes de tentar queria consultar alguém mais experiente para me indicar melhor forma de fazer isso, se pudesse me dar algumas dicas de como fazer os desenhos porque na internet só encontro exemplos simples :\. A estrutura que eu estou usando é assim:

    Desenho:
    Jogo chama método da classe player;

    Player detecta pressionamento de teclas, chama método de desenho da classe do personagem atual, chama método da classe da fase atual para fazer o desenho;

    personagem atual: faz seu desenho e o desenho de seus ataques ataques(quando ativados);

    Fase atual: Desenho do cenário e de suas criaturas(quando ativadas pela presença do player);

    Agradeço desde já pela atenção e pela ajuda.

  • ViniGodoy
    avatar

    Antes de pirar na batatinha, use um profiler. Essa aplicação de partículas pinta milhares de objetos na tela, a mantem um FPD alto:
    http://www.pontov.com.br/files/outros/vinigodoy/particles/particles.ht ml

    Talvez seja algum problema diferente, como você estar carregando algum recurso dentro do gameloop.

  • Pedro Henrique  - Melhor componente
    avatar

    Bom dia, tudo bem? Qual o melhor componente para eu carregar imagens? JPanel, JFrame? Pois pretendo fazer um editor. Obrigado

  • ViniGodoy
    avatar

    Depende. Se você quiser usar a imagem em vários tipos de janela, então, melhor usar um JPanel ou um JComponent. Caso você precise de imagens que se movam numa taxa constante de quadros, você pode diretamente sobre o JFrame.

  • Wilian diogo  - Criar um "máscara" transparente tipo matriz em u
    avatar

    Olá pessoal, primeiramente parabéns pelo post...

    Tenho uma imagem que é uma planta da empresa, preciso gravar dados em um bd e recuperá-los depois marcando e mostrando o local de um acidente de trabalho mostrando na imagem, no caso na imagem da planta da empresa. Como se fosse um marcador, um ícone etc.

    Pensei em dividir a imagem ( cortar em pedaços) a planta porem iria ter umas 200 imagens... Existe uma maneira de conseguir isso? ou uma maneira de criar uma espécie de matriz transparente em cima da planta?
    Abraço galera...

  • Ytrio salmito
    avatar

    Boa tarde pessoal :)
    Eu estou tentando fazer um jogo de nave utilizando API Java 2D.
    E estou tendo dificuldade em saber como ocultar a imagem para em um método drawImage.
    Vocês sabem me dizer se isso é possível ?...?

  • ViniGodoy
    avatar

    Simplesmente não chame o método. Ponha-o dentro de um if, fazendo com que só seja chamado caso a nave esteja visível.

  • Bruno  - Como desenhar uma imagem direto na pagina
    avatar

    Olá pessoal,
    Artigo muito bom, mas estou com um outro problema, preciso pegar uma imagem do meu banco de dados e carrega-la direto na pagina, pego a imagem e consigo gravar em disco, mas não consigo desenha-la direto na pagina. Alguém pode me ajudar a fazer isso?

  • David Araújo  - Matriz 3x3 que leia uma imagem e mostre pixel a pi
    avatar

    Ola amigo, vi um post seu sobre matriz e imagem...

    estou tentando fazer uma matriz pra ler uma imagem e mostrar pixel a pixel, você poderia me ajudar?

    Segue meu código.

    public static void main(String[] args) throws IOException {

    String matriz = null;
    //int [][] col, lin = {};
    //int [][] col, lin = {};

    BufferedImage imagem = ImageIO.read(new File("/D/img/windows.jpg";));// carregando imagem desse diretorio
    int w = imagem.getWidth(); //Largura
    int h = imagem.getHeight(); // Altura
    int[] pixels = imagem.getRGB(0, 0, w, h, null, 0, w);
    Random r = new Random();


    for (int col=0; col< w; col++) {
    for (int lin=0; lin

  • Leonardo  - Compactar imagem
    avatar

    Olá, como posso compactar uma imagem sem perder qualidade? Ou escolher o quanto desejo perder de qualidade na imagem?

  • Vinicius Godoy
    avatar

    Salve a imagem em png. Ele é um formato sem perda de qualidade (lossless). Caso salva em jpg, você até pode escolher a qualidade usando o código que coloquei na resposta desse tópico.

  • João Fernandes
    avatar

    Não entendi o segundo método drawImage, utilizei um parecido no android e funcionou mas este ae do Java2D é muito mais complexo, olha só:

    - o primeiro parâmetro eu passo a imagem

    - os 4 primeiros inteiros formam um retângulo onde, que é onde a imagem será desenhada, x, y, w e h, se w e h forem diferentes dos w e h da fonte, a imagem será redimensionada(ficando maior ou menor)

    - os próximos 4 inteiros são o retângulo da fonte, a porção da imagem que quero desenhar.

    Possuo uma imagem de 64x64 e utilizei o método da seguinte forma para desenhar apenas 25% da imagem:

    g2d.drawImage(image_test, 200, 200, 32, 32, 0, 0, 32, 32, null);

    O que deveria fazer seguindo a lógica da explicação? desenhar os primeiros 25% da imagem na posição 200x200 da tela com as dimensões de 32x32, ou seja, o tamanho permaneceria inalterado, no entanto o que eu recebi foi uma imagem aumentada e invertida(cabeça pra baixo), pelo menos os 25% foram cortados corretamente, o que me leva a crer que minha interpretação do retângulo do destino está incorreta.

    Se puder me ajudar nessa parte eu agradeço

  • Vinícius Godoy de Mendonça
    avatar

    Os parâmetros são x1, y2, x2 e y2.
    E não x, y, w e h, como você escreveu.

    Portanto, seu drawImage deveria ser:
    g2d.drawImage(image_test, 200, 200, 232, 232, 0, 0, 32, 32, null);

    Usam x2 e y2 ao invés de altura e largura justamente para permitir que você inverta a imagem. ;)

  • João Fernandes
    avatar

    hmm, funcionou agora, valeu :silly:

  • Julia
    avatar

    Olá, gostaria de saber se tem como fazer um Jbutton com uma imagem e como eu poderia fazer isso? Obrigada

  • Venicius  - Carregar imagem PGM
    avatar

    Olá, gostaria de saber como faço para carregar uma imagem no formato PGM para um panel

  • Anônimo  - exibir apenas uma cor na imagem
    avatar

    Seguinte tenho varias imagens que vão ficar sobre postas das quais apenas a mais inferior ficará totalmente visível e as camadas acima dela deverão exibir apenas uma determinada cor.
    Como posso fazer isso?
    Obrigado.

  • Adeilson  - E possivel criar uma imam
    avatar

    Ola e possivel criar(gerar) uma imagem (desenhando) do zero com java e salva - la com uma extenção por exemplo jpg,png,...etc

  • Rodrigo  - Imprimir uma lista de imagens
    avatar

    Olá Vinícius!
    Eu queria te perguntar como fazemos quando vamos imprimir uma lista de imagens. Por exemplo, quando uso o método ImageIO.write(), ele me retorna uma imagem em meu servlet. Só que ai eu terei só uma unica imagem na tela do navegador. Eu tinha até criado um loop que recebia varias imagens diferentes de uma lista, e ia escrevendo. Mas no final sempre retornava um imagem e não uma lista.
    Se não puder responder, vou entender. Obrigado.

  • RODRIGO MAGALHÃES  - Processamento de Imagens
    avatar

    Muito bom o artigo! Parabéns. Estou querendo usar as dicas em um trabalho na disciplina de Processamento de Imagens. Tenho que gerar uma matriz de pixels a partir de uma imagem e depois fazer interpolações.

  • EDMILSON  - colocar uma imagem na janela padrão da java
    avatar

    como faço para inserir uma imagem onde fica xicara em qual quer app java

Escrever um comentário
Your Contact Details:
Gravatar enabled
Comentário:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch::(:shock:
:X:side::):P:unsure::woohoo::huh::whistle:;):S:!::?::idea::arrow:
Security
Por favor coloque o código anti-spam que você lê na imagem.
LAST_UPDATED2  

Busca

Linguagens

Twitter