![]() |
|
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.
-
13/12/2009 17:46:40 | Vinícius Godoy de Mendonça
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).
-
15/01/2010 16:50:09 |200.19.97.xxx| Eduardo Skrepnek Tosin - Excelente
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.
-
15/01/2010 16:55:00 | Vinícius Godoy de Mendonça - Flickering e Buffer
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.
-
05/02/2010 11:31:57 |200.171.88.xxx| seudito - Modo assíncrono
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!
-
05/02/2010 11:37:04 | Vinícius Godoy de Mendonça
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.
-
27/08/2010 12:01:02 |189.19.230.xxx| Anônimo - Informação
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?
-
27/08/2010 12:21:56 | Vinícius Godoy de Mendonça
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.
-
29/10/2010 21:02:45 |187.107.150.xxx| Xilon
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......
-
30/12/2010 04:11:12 |200.232.132.xxx| Mateus - Duas perguntas
Tem como eu rotacionar uma imagem ou espelha-la?
-
30/12/2010 11:57:55 | Vinícius Godoy de Mendonça
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().
-
16/02/2011 19:16:28 |201.67.111.xxx| adailton - carregar gif
cara tem como carregar uma imagem no java no formato gif ou algo assim?
-
17/02/2011 00:29:29 | Vinícius Godoy de Mendonça
Tem sim, é só seguir o que está escrito nesse artigo.
-
14/04/2011 17:52:12 |201.86.95.xxx| Leandro
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
-
14/04/2011 18:26:45 | Vinícius Godoy de Mendonça
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)
-
14/04/2011 19:19:33 |201.86.95.xxx| Leandro - re: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.
-
14/04/2011 19:19:24 | Vinícius Godoy de Mendonça
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
-
22/04/2011 04:26:31 |189.15.122.xxx| Davi - IloveVINI
vinivnivnivni.. não é a primeira vez q vc me salva!
bom trabalho!!
-
31/08/2011 17:49:06 |189.70.116.xxx| allan
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?
-
31/08/2011 17:53:33 | Vinícius Godoy de Mendonça
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).
-
31/08/2011 17:56:57 |189.70.116.xxx| allan
como eu faço para saber se a imagem do inimigo colidiu com a imagem do inimigo?
-
31/08/2011 18:05:51 | Vinícius Godoy de Mendonça
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.
-
26/10/2011 00:14:52 |187.16.242.xxx| washington - Redimensionar imagem
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.";
}
}
-
26/10/2011 11:22:48 | Vinícius Godoy de Mendonça
Use o JImagePanel do projeto towel:
https://github.com/MarkyVasconcelos/T owel/blob/master/src/com/towel/swing/img/JImagePanel.java
-
07/01/2012 12:54:25 |201.86.138.xxx| wilson - Recuperar a imagem sobreposta
No item
esenhando 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();
-
07/01/2012 13:23:55 | Vinícius Godoy de Mendonça
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");
-
24/02/2012 14:05:26 |187.64.143.xxx| David Rocha - Imagem sobre outra imagem
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?
-
24/02/2012 14:10:05 | Vinícius Godoy de Mendonça
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.
-
24/02/2012 14:26:07 |187.64.143.xxx| David Rocha - Imagem sobre imagem
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?
-
24/02/2012 14:57:46 | Vinícius Godoy de Mendonça
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.
-
20/03/2012 21:47:46 |189.124.193.xxx| Hugo Carvalho
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 geradoalguma dica ?!
-
21/03/2012 12:08:01 | Vinícius Godoy de Mendonça
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ê.
-
07/08/2012 03:21:43 |177.98.110.xxx| Douglas - Manipulação de imagens com lentidão.
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.
-
07/08/2012 11:16:56 | Vinícius Godoy de Mendonça
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/
-
07/08/2012 16:44:46 |189.27.126.xxx| deyverson - duvida sobre maquiagem digital
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
-
07/08/2012 16:58:09 | Vinícius Godoy de Mendonça
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.
-
26/10/2012 04:29:34 |177.191.80.xxx| Adriano dos Santos - Trabalhos com 3D
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.
-
03/11/2012 23:19:16 |186.241.201.xxx| Douglas - Aplicação em Java para web
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.
-
04/11/2012 09:26:46 | Vinícius Godoy de Mendonça
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.
-
04/11/2012 15:39:16 |186.241.201.xxx| Douglas
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.
-
15/11/2012 23:35:56 |177.40.7.xxx| Ricardo - JImagePanel com GIF
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.
-
16/11/2012 16:56:12 |177.179.157.xxx| Douglas - Duração de mídias com JMF
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.
-
20/03/2013 03:49:21 |177.157.86.xxx| Thiago - Redimensionar imagens
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ç
-
20/03/2013 12:40:48 |189.101.67.xxx| Vinícius Godoy
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.
-
20/03/2013 14:32:03 |177.157.86.xxx| Thiago - Redimensionar imagens
Olá Vinícius,
poderia me dar um código de exemplo de como poderei liberar memória do heap da VM?
Obrigado.
-
02/04/2013 13:59:07 |201.48.90.xxx| Tania Silva - Processamento de Imagem
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");
}
}
-
02/04/2013 14:01:48 |189.101.67.xxx| ViniGodoy
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
-
02/04/2013 20:41:35 |187.32.226.xxx| Tania - Ah sim
Verdade, obrigada
Conheci hoje seu portal, parece ser ótimo, visitarei sempre, pois estou trabalhando paralelamente com desenvolvimento de jogos também!
Obrigada!
-
22/05/2013 03:45:38 |187.18.177.xxx| igor carneiro - Comparando Cartao resposta
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.
-
22/05/2013 13:59:34 |189.101.67.xxx| Vinicius Godoy
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.
-
22/05/2013 15:06:02 |187.19.198.xxx| igor carneiro
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.
-
22/05/2013 18:02:05 |189.101.67.xxx| ViniGodoy
Eu entendi exatamente o seu problema, e tudo que eu falei ainda vale.
-
01/06/2013 01:16:37 |187.18.177.xxx| Anônimo - re: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 ????
-
22/05/2013 14:39:19 |177.133.11.xxx| Thiago - Lentidão ao redimensionar
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.
-
22/05/2013 15:08:48 |187.19.198.xxx| igor carneiro - re: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.
-
22/05/2013 18:01:31 |189.101.67.xxx| ViniGodoy
Use jnlp para que o applet tenha acesso a placa de vídeo.
-
30/05/2013 13:49:12 |177.132.254.xxx| thiago - Japplet + html
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.
-
08/07/2013 10:30:37 |177.68.168.xxx| Erik Guilherme Tartaglia - Instrução createCompatibleImage(...)
Muito bom seu site, serve de um bom norteio para quem esta começando (meu caso
).
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?
-
19/07/2013 09:59:35 |189.58.2.xxx| ViniGodoy
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.
-
19/07/2013 01:45:22 |187.44.30.xxx| Paulo - desenhando várias imagens
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.
-
19/07/2013 09:58:22 |189.58.2.xxx| ViniGodoy
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 mlTalvez seja algum problema diferente, como você estar carregando algum recurso dentro do gameloop.
-
20/09/2013 10:58:40 |200.195.162.xxx| Pedro Henrique - Melhor componente
Bom dia, tudo bem? Qual o melhor componente para eu carregar imagens? JPanel, JFrame? Pois pretendo fazer um editor. Obrigado
-
20/09/2013 15:50:02 |189.101.67.xxx| ViniGodoy
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.
-
17/02/2014 17:00:16 |177.183.242.xxx| Wilian diogo - Criar um "máscara" transparente tipo matriz em u
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...
-
03/03/2014 20:31:16 |187.79.43.xxx| Ytrio salmito
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 ?...?
-
04/03/2014 00:50:44 |177.40.52.xxx| ViniGodoy
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.
-
14/03/2014 22:37:16 |177.17.130.xxx| Bruno - Como desenhar uma imagem direto na pagina
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?
-
03/04/2014 12:46:59 |177.0.28.xxx| David Araújo - Matriz 3x3 que leia uma imagem e mostre pixel a pi
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
-
18/05/2014 18:18:43 |186.218.0.xxx| Leonardo - Compactar imagem
Olá, como posso compactar uma imagem sem perder qualidade? Ou escolher o quanto desejo perder de qualidade na imagem?
-
18/05/2014 20:57:13 |201.21.151.xxx| Vinicius Godoy
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.
-
18/05/2014 20:54:33 |187.44.30.xxx| João Fernandes
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
-
18/05/2014 21:01:33 | Vinícius Godoy de Mendonça
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.
-
23/08/2014 00:55:45 |187.59.36.xxx| Julia
Olá, gostaria de saber se tem como fazer um Jbutton com uma imagem e como eu poderia fazer isso? Obrigada
-
25/08/2014 19:31:21 |201.49.202.xxx| Venicius - Carregar imagem PGM
Olá, gostaria de saber como faço para carregar uma imagem no formato PGM para um panel
-
15/10/2014 13:53:19 |201.73.104.xxx| Anônimo - exibir apenas uma cor na imagem
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.
-
24/12/2014 21:41:05 |201.92.220.xxx| Adeilson - E possivel criar uma imam
Ola e possivel criar(gerar) uma imagem (desenhando) do zero com java e salva - la com uma extenção por exemplo jpg,png,...etc
-
11/09/2015 21:59:20 |32.59.181.xxx| Marcus Vinicius
Olá, sou novato em java e gostaria de tirar uma dúvida.
Estou tentando usar imagens no meu programa, qndo rodo no eclipse roda td bem, mas qndo compilo as imagens não aparecem. As imagens estão em uma pasta imagens dentro da bim.
Busquei ajuda em outros Fóruns mas ainda não me ajudaram.Referenciei as imagens no inicio do script sa seguinte forma
;<br /> Icon rela = new ImageIcon("bin/Imagem/relat.png"<br /> Icon envio = new ImageIcon("bin/Imagem/relat.png"
;' rel='external nofollow' title='Icon chat = new ImageIcon("bin/Imagem/chat.png"
;<br /> Icon rela = new ImageIcon("bin/Imagem/relat.png"
;<br /> Icon envio = new ImageIcon("bin/Imagem/relat.png"
;'>Icon chat = new ImageIcon("bin/Imagem/chat.png"
;<br /> Icon rela = new ImageIcon("bin/Imagem/relat.png"
;<br /> Icon envio = new ImageIcon("bin/Imagem/relat.png"
;
E por último, esta que usei para colocar uma imagem de fundo
; // imagen fundo<br /> La1 = new JLabel(Im1);<br /> La1.setLocation(0, 0);<br /> La1.setVisible(true);<br /> <br /> <br /> P1 = new JPanel(); // Fundo<br /> P1.setOpaque(false);<br /> P1.setBounds(0, -10, 1400, 800);<br /> P1.setBackground(Color.white);<br /> P1.add(La1, BorderLayout.NORTH);<br /> Im1 = new ImageIcon("bin/Imagem/tietes.jpg"<br /> La1.setIcon(Im1); ' rel='external nofollow' title='Im1 = new ImageIcon(""
; // imagen fundo<br /> La1 = new JLabel(Im1);<br /> La1.setLocation(0, 0);<br /> La1.setVisible(true);<br /> <br /> <br /> P1 = new JPanel(); // Fundo<br /> P1.setOpaque(false);<br /> P1.setBounds(0, -10, 1400, 800);<br /> P1.setBackground(Color.white);<br /> P1.add(La1, BorderLayout.NORTH);<br /> Im1 = new ImageIcon("bin/Imagem/tietes.jpg"
;<br /> La1.setIcon(Im1); '>Im1 = new ImageIcon(""
; // imagen fundo<br /> La1 = new JLabel(Im1);<br /> La1.setLocation(0, 0);<br /> La1.setVisible(true);<br /> <br /> <br /> P1 = new JPanel(); // Fundo<br /> P1.setOpaque(false);<br /> P1.setBounds(0, -10, 1400, 800);<br /> P1.setBackground(Color.white);<br /> P1.add(La1, BorderLayout.NORTH);<br /> Im1 = new ImageIcon("bin/Imagem/tietes.jpg"
;<br /> La1.setIcon(Im1);
Desculpem usar aqui para postar esta dúvida mas já tentei de td pra tentar resolver isso.
Me ajudem por favor!!!
-
16/11/2015 16:05:03 |177.152.168.xxx| Rodrigo - Imprimir uma lista de imagens
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.
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!