Como diminuir resolução de uma imagem?

I ae galera
Pesquisei muito no guru google soh q nao encontrei nada =/
Meu problema é o seguinte

Eu quero diminuir a resolução da imagem sem cortar nada da imagem, apenas diminui-la, exemplo passar uma imagem de 600x600 para 640x400.

Eu carrego a minha imagem da seguinte maneira

File image = new File("imagem.jpg");

Como eu poderia fazer isso?

Atenciosamente

1 curtida

O primeiro passo é carregar sua imagem num BufferedImage:

BufferedImage imagem = ImageIO.read(new File("imagem.jpg"));

Depois, você tem várias opções:

  1. Usar o método getScaledInstance() da classe image:
Image imagemMenor = imagem.getScaledInstance(600, 400);

Vantagens: Simples de escrever
Desvantagens: Retorna um objeto do tipo Image, o que praticamente inviabiliza mais manipulações na imagem.

  1. Fazer a cópia da imagem:

BufferedImage novaImagem = new BufferedImage(600,400, imagem.getType()); Graphics2D g2d = novaImagem.createGraphics(); g2d.drawImage(imagem, 0, 0, 600, 400, null); g2d.dispose();

Vantagens: Permite manipulações futuras na imagem. Também permite definir a qualidade gráfica usando o método setRenderingHints do Graphics2D.
Desvantagens: Mais código.

  1. Criar um affine transform, e fazer a cópia da imagem:

AffineTransform transform = AffineTransform.getScaleInstance(600, 400); BufferedImage novaImagem = new BufferedImage(600,400, imagem.getType()); Graphics2D g2d = novaImagem.createGraphics(); g2d.drawImage(imagem, transform, null); g2d.dispose();

Vantagens: Permite várias transformações simultâneas (como também rotação, espelhamento, deslocamento). Usa apenas uma operação de pintura, seja qual for o número de transformações. Permite transformações customizadas. E também permite que você use uma matriz de transformação previamente salva.
Desvantagens: Método mais complexo dos três, especialmente se usar uma matriz de transformação definida matematicamente.

muito obrigado viny

Tutorial na minha pastinha de dicas em java ^^

Tenho mais uma duvida agora viny, como eu faço pra gravar um arquivo JPEG da imagem no disco?

Muito obrigado novamente ^^

Use o método ImageIO.write.

Opa viny deu certinho

Muito obrigado

Estou usando o segundo metodo de criar uma nova imagem com BufferedImagem, akele do getScaledInstance seria até que bom, mas nao descobri o jeito de gravar a Image com o ImageIO.write, pq ele pede um RenderedImage por parametro =/

Testei e soh aceita com BufferdImage, tenho q dar uma estuda melhor sobre como trabalhar com imagens

Obrigado novamente

Eu não uso o primeiro método pra nada. É menos otimizado que os outros, menos flexível também.

entendi ^^
Eu disse q pro meu caso até q serviria pq oq eu preciso apenas eh diminuir o tamanho da imagem, q eu vou gravar no banco e se o usuario for colocar uma imagem de 2Mega ae ferra o banco iuahiuahuiah
Mais eu to estudando uma forma de conseguir implementar para apenas gravar o caminho da imagem no banco
Meu colega me deu uma ideia, soh q nos ainda nao testamos pra ver se da certo

Tu sabe me informar até qts mega de banco o mysql consegue trabalhar bem?

Falows

Esses opções de códigos que vc colocou, ViniGodoy, tmb serve para aumentar uma imagem?

Sim. :wink:

entao, no caso, ele irá fazer isso automaticamente? ou seja, conforme o tamanho q eu especifiquei, ele vai verificar a imagem carregada pelo usuário, e ai sim, diminui ou aumenta a imagem, certo?

Certo. O tamanho que você passar é o tamanho que ele vai deixar a imagem. Simples assim.

Mas, por exemplo, eu tenho um selecionador de arquivos (jFileChooser), e nele, o usuário escolhe a imagem. Dessa imagem, eu retiro apenas o caminho dela, e jogo no banco. No meu programa, em um local especifico, ele ñ vai chamar a imagem, mas sim o caminho dela. E agora, onde coloco o trecho abaixo, sendo q ele se refere a imagem, em especifico, e ñ ao caminho?

BufferedImage imagem = ImageIO.read(new File("imagem.jpg"));  

O trecho do meu programa, em que preciso de sua orientação, é esse:

[code]private void botaoImagemActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
new BotaoSom();
if (!"".equals(recebeID.getText())&&!"".equals(recebeAlt1.getText())&&!"".equals(recebeAlt2.getText())&&!"".equals(recebeAlt3.getText())&&!"".equals(recebeAlt4.getText())&&!"".equals(recebePerg.getText())&&!"".equals(recebeResposta.getText()))
{
try
{
JFileChooser Image = new JFileChooser();
Image.setCurrentDirectory (new File ("/Meus documentos/"));
Image.setDialogTitle (“Inserir imagem na pergunta:”);
int res = Image.showOpenDialog(null);
if(res == JFileChooser.OPEN_DIALOG)
{
String foto = Image.getSelectedFile().getCanonicalPath().replace("\", “/”);

           String escolhe = opcaoImagem.getSelectedItem().toString();
           String sql = "UPDATE facil SET " +
           "imagem = '"+ foto +"', " +   
           "tipoimagem = '"+ escolhe +"'" +
           "WHERE id = '"+ recebeID.getText() +"'";
           int r = BD.runSQL(sql);
           new CorretoSom();
           JOptionPane.showMessageDialog(null, "Você escolheu um(a) " + escolhe + " a ser exibido(a) na pergunta!","Inserir Imagem:",JOptionPane.INFORMATION_MESSAGE);
           BD.resultSet.refreshRow(); 
           labelTipoImagem.setText(escolhe); 
           mostraTipo();
        } 
        if(res == JFileChooser.CANCEL_OPTION)
        {
            new FimJogoSom();
            JOptionPane.showMessageDialog(null, "Você não escolheu nenhuma imagem!","Inserir Imagem:",JOptionPane.WARNING_MESSAGE);
        }     
    }   
    catch (Exception erro)   
     {   
        JOptionPane.showMessageDialog (null,erro);   
     }
    }
}   [/code]

E onde vc precisa carregar uma imagem?

É o usar o getSelectedFile retornado com caminho no image io.

Outra coisa, pq vc comparar o JFileChooser com o OPEN_DIALOG? Não deveria ser APPROVE_OPTION?
Finalmente, o parâmetro do método showOpenDialog deveria ser this não null.

[i]Desculpa a demora em responder ViniGodoy, estive por um tempo longe do pc, por causa das festas de fim de ano…

Então, estive vendo meu código hj, e te mandei o trecho errado, por isso que estava dando errado, creio eu que seja nesse trecho, que eu preciso colocar o código:

public PerguntaFacil() { atualizaCampo(); if(Pontos.fimJogo==true) this.dispose(); initComponents(); labelImagem.setIcon(new ImageIcon(imagem)); labelTempo.setVisible(true); conta = new Contador (labelTempo); labelTempo.setText("00:00:00"); conta.start(); }

creio q antes de labelImagem.setIcon(new ImageIcon(imagem));, seria essas linhas:

BufferedImage MudarImagem = ImageIO.read(new File(imagem)); Image ImagemMudada = MudarImagem.getScaledInstance(458, 367);

Só q no meu código, essa segunda linha, desse ultimo trecho q código q vou colocar, fica sempre em vermelho, e ñ entendo o q esta d errado nela, o q será?

Obs: o método “atualizaCampo()” chama dados do mysql, e “imagem” recebe o caminho completo de uma imagem q vem do banco, e é a imagem desse caminho, q preciso aumentar ou diminuir.[/i]

Colocando o mouse sobre a linha vermelha, que erro que ele indica?

getScaledInstance(int,int,int) in java.awt.Image cannot be applied to (int,int)

incompatible types
found :java.awt.image.BufferedImage.getScaledInstance
required :java.awt.Image

Bom, é só ler o JavaDoc do método getScaledStance:
http://download.oracle.com/javase/6/docs/api/java/awt/Image.html#getScaledInstance(int,%20int,%20int)

O certo é fazer:

Image ImagemMudada = MudarImagem.getScaledInstance(458, 367, Image.SCALE_SMOOTH);  
1 curtida

Obrigada ViniGodoy, deu certinho aqui!!! ;D

Só tenho que arrumar uns erros que deu no jogo agora, pois esta rodando errado, mas a questão d imagem, esta certo!! ;]

Só me responda uma coisa, q acho q vai ser util pra esse erro q preciso arrumar:

sabe o SCALE_SMOOTH, q vc colocou naquela linha? entao, pra q q ele serve?

e os demais, como:
SCALE_DEFAULT
SCALE_FAST
SCALE_REPLICATE
SCALE_AREA_AVERAGING
qual a utilidades dele?

grato pela atenção!!! ;D

Ele diz ao java qual é a qualidade do algorítmo de escalonamento.

O DEFAULT permite que o Java escolha ele mesmo o algoritmo.
O FAST usa um algorítmo rápido, mas de baixa qualidade.
O SMOOTH usa um algorítmo que prioriza a qualidade do desenho.

Os outros dois são nomes dos algorítmos, usados provavelmente nas operações acima. Eu prefiro não utiliza-los, pois permite que o Java escolha algorítmos melhores no futuro. Use-os somente se você precisa garantir que o algoritmo será conhecido:

O REPLICATE é provavelmente usado no FAST. Aumenta a imagem simplesmente replicando linhas ou colunas, ou as excluindo.
O AVERAGING tira a média das cores dos pixels vizinhos, para produzir um pixel mais gradual. É também chamada de filtragem bilinear. Provavelmente é usado no SMOOTH.

Olá ViniGodoy!

Obrigada pela resposta, mas pelo jeito ñ tem haver com o que eu precisava…

Se vc puder me auxiliar novamente, é o seguinte:

Tenho um jogo, que criei no meu curso de técnico em informática, mas q vou dar continuidade nesse ano, em que vou entrar para a faculdae. Ele é um quiz educacional, onde o professor inseri as perguntas, e o aluno responde.

Além das questões, o professor pode adicionar uma imagem à ela. Só que após reformular alguns erros (com o código desse tópico), vi que gerou mais um erro, mas que esta apenas por uma linha de codificação, para ser solucionado (e é esse linha que eu ñ sei).

Imagine que eu tenho um jFrame, e nele, a pergunta, com 4 alternativas e uma imagem, são mostradas. só que ao ir para a segunda questão, e se ela ñ tiver imagem, ele no caso atualiza todos os campos de pergunta e alternativas, mas ñ atualiza o de imagem, que deveria aparecer vazio, mas que aparece com a imagem da pergunta anterior. E é dessa linha que preciso, fazer com que o meu jLabel, que mostra a imagem, de um tipo de jLabel.clear() para limpar o conteúdo existente nele, e chamar o conteudo atual, q no caso, é vazio, deixando o jLabel em branco.

Por fim, este trecho de código agora esta assim:

public PerguntaFacil() { try { atualizaCampo(); if (Pontos.fimJogo == true) { this.dispose(); } initComponents(); labelTempo.setVisible(true); conta = new Contador(labelTempo); labelTempo.setText("00:00:00"); conta.start(); if (imagem != null) { BufferedImage MudarImagem = ImageIO.read(new File(imagem)); Image ImagemMudada = MudarImagem.getScaledInstance(458, 367, Image.SCALE_SMOOTH); labelImagem.setIcon(new ImageIcon(ImagemMudada)); } else { labelImagem.setIcon(new ImageIcon(imagem)); } } catch (IOException ex) { Logger.getLogger(PerguntaFacil.class.getName()).log(Level.SEVERE, null, ex); } }

Obrigada!!! ;]