Redimensionar Imagens WEB

Pessoal,
Boa tarde

Eu não estou sabendo redimensionar imagens.

Já estou gravando a imagem mas agora preciso redimensiona-la, vi algo sobre o assunto mas nada que eu fiz deu certo. Alguem pode me ajudar?
Não encontrei tutorial nenhum de como redimensionar imagens na net. Vi só um monte de código que não esta funcionando qndo adequo ele ao meu codigo mas nada de algo explicativo. Pra falar a verdade nem sei onde colocar o redimensionamento no meu codigo abaixo:

package control;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

import model.ConexaoMysql;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class ServletUpload extends HttpServlet{
 
    //Initialize global variables
    public void init() throws ServletException {
    }
    
  //Process the HTTP Get request
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	doPost(request, response);	
    }

    public ConexaoMysql conexaoMysql;
    
    //Process the HTTP Post request
    public void doPost(HttpServletRequest request, HttpServletResponse response) 

                       throws ServletException, IOException {
		
/*		PrintWriter out = response.getWriter();
    	out.println("ESSE É O ID: " + id);
    	out.println("ESSE É O NUMFOTO: " +  numFoto);
    	out.flush();
    	out.close();*/
	
        boolean isMultiPart = FileUpload.isMultipartContent(request);
        
        if (isMultiPart) {
            FileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            String formulario = "";
            String id         = "";
            String numFoto    = "";
        
            try {
                List items = upload.parseRequest(request);
                Iterator iter = items.iterator();
                
                while (iter.hasNext()) {
                    FileItem item = (FileItem) iter.next(); 
                    
                    for (Object o : items){
                    	//System.out.println(o.toString());
                    	FileItem fi = ( FileItem ) o;
                    	
                    	if (fi.getFieldName().equals("tipoForm")) {
                            formulario = fi.getString();
                        }
                        
                        if (fi.getFieldName().equals("id")) {
                            id = fi.getString();
                        }
                        
                        if (fi.getFieldName().equals("numFoto")) {
                            numFoto = fi.getString();
                        }
                    }
                
                    if (!item.isFormField()) {
                        if (item.getName().length() > 0) { //item.getName() - é o endereço do arquivo, endereço de origem.
                        	this.inserirImagemDiretorio(item, id, numFoto);
                        }
                    }
                }
            } catch (FileUploadException ex) {
            	ex.printStackTrace();
            }  catch (Exception ex) {
            	ex.printStackTrace();
            }
        }
        
    }
    // implementação de demais métodos do Servlet.
    

/**
 * 
 * @param item FileItem, representa um arquivo que é enviado pelo formulario

 * MultiPart/Form-data
 * @throws IOException
 */
    private void inserirImagemDiretorio(FileItem item, String id, String numFoto) throws
                                                     IOException {
    	conexaoMysql = new ConexaoMysql();
    	
        //Pega o diretório /logo dentro do diretório atual de onde a 
        //aplicação está rodando
        String caminho = getServletContext().getRealPath("/logo") 
                         + "/";
        
         // Cria o diretório caso ele não exista
        File diretorio = new File(caminho);
        if (!diretorio.exists()){
            diretorio.mkdir();
        }

        // Mandar o arquivo para o diretório informado
        String nome = item.getName();
        String arq[] = nome.split("\\");
        for (int i = 0; i < arq.length; i++) {
            nome = arq[i]; //isso aqui é o nome do arquivo em si... o nome que ele pega do usuario.
        }
        
       // System.out.println("Esta é a variavel NOME: " + nome);        
        
        File file = new File(diretorio, nome);
        FileOutputStream output = new FileOutputStream(file);
        InputStream is = item.getInputStream();
        byte[] buffer = new byte[2048];
        int nLidos;
        while ((nLidos = is.read(buffer)) >= 0) {
            output.write(buffer, 0, nLidos);
        }
        output.flush();
        output.close();

		//Guarda no banco de dados o endereço para recuperação da imagem
		
		Connection conexao = null;
		
		/**
		Estabeleça a conexão
		*/

  		PreparedStatement pstmt = null;

       // String sql = "INSERT INTO TabelaTeste2 (codigo, imagem) VALUES(?, ?)";

  		String sql = "update contratosimportantes set foto"+numFoto+" = ? where id = ?";
  		
        try {
        	  pstmt = conexaoMysql.conexao.prepareStatement(sql);
              //declaracao = conexao.prepareStatement(sql);
              
        	  String novoCaminho = "logo/" + nome;
        	  
              pstmt.setString(1, novoCaminho); // codigo 1
              pstmt.setString(2, id);
              //pstmt.setString(2, caminho);
              
              pstmt.executeUpdate();
              
        } catch (SQLException sqlEx) {
              sqlEx.printStackTrace();
        } catch (Exception ex) {
              ex.printStackTrace();
        }
	}
}

Image

Eder, queria um exemplo mais prático e mais fácil. Não sei também quais são os procedimentos para redimensionar a imagem… por exemplo, primeiro pega a imagem olha o tamanho dela e manda ela ficar do tamanho que eu quero… acho que não é tão simples assim, pelo menos pelos codigos que vi. Não sei se quer os comandos direito.

Para o redimensionamento vou ter que mudar todo o meu código ou vou poder aproveita-lo?

Pessoal, dá uma força ai por favor

Olá Ellensmp,

O método que te passei retorna uma nova instância de Image, com base na largura (width) e altura (height) informados. O parâmetro hints especifica qual algorítmo (ver variáveis estáticas da classe Image) será utilizado.

Para criar um objeto Image, você pode utilizar a classe ImageIcon.

Que informações você possui sobre a imagem?

Caso possua o endereço do arquivo:

ImageIcon icon = new ImageIcon( "filename" );
Image image = icon.getImage();

Image imageScaled = image.getScaledInstance( width, height, Image.SCALE_DEFAULT );

Caso possua um array de bytes representando o arquivo (imagem):

byte[] imageData;
ImageIcon icon = new ImageIcon( imageData );
Image image = icon.getImage();

Image imageScaled = image.getScaledInstance( width, height, Image.SCALE_DEFAULT );

[quote=Eder Peixoto]Para criar um objeto Image, você pode utilizar a classe ImageIcon.

Que informações você possui sobre a imagem?[/quote]

O meu codigo acima funciona perfeitamente. Eu pego a imagem, gravo ela em disco e coloco o endereço/caminho dela no bd.

Preciso apenas, se possivel, adequar/aprender a fazer um codigo para redimensionamento. O que vc me passou foi a API.

[quote=Eder Peixoto]Caso possua o endereço do arquivo:

ImageIcon icon = new ImageIcon( "filename" );
Image image = icon.getImage();

Image imageScaled = image.getScaledInstance( width, height, Image.SCALE_DEFAULT );

Caso possua um array de bytes representando o arquivo (imagem):

[code]
byte[] imageData;
ImageIcon icon = new ImageIcon( imageData );
Image image = icon.getImage();

Image imageScaled = image.getScaledInstance( width, height, Image.SCALE_DEFAULT );
[/code][/quote]

É só acrescentar isso aqui ao meu codigo? Caso afirmativo onde acrescento?

ImageIcon icon = new ImageIcon( "filename" );   
Image image = icon.getImage();   
  
Image imageScaled = image.getScaledInstance( width, height, Image.SCALE_DEFAULT );  

Pego só uma imagem e outros dados do form.

O que seria “FILENAME”? O nome do arquivo, que no meu codigo seria entao a variavel ‘nome’? ou seria oq?
Width e Height é o que? Não passo os valores para ele? Deve ser assim neh:

ImageIcon icon = new ImageIcon( nome );   
Image image = icon.getImage();   
  
Image imageScaled = image.getScaledInstance( 100, 100, Image.SCALE_DEFAULT );  

Já vi algo que qndo a imagem for retangular ( a maioria das minhas são) ela distorce. Tem isso mesmo?

Isso é muito chato, cheio de coisinhas… penei para gravar a imagem no banco e agora tenho que redimensiona-la

Você que definirá. Poderá criar um método específico, por exemplo.

O nome e endereço do arquivo (uma URI).

Width: nova largura da imagem.
Height: nova altura da imagem.

Sim, deve-se informar valores inteiros.

Para haver a menor distorção possível, mantenha as mesmas proporções.

O algorítmo que for informado é que determinará o nível de distorção da imagem. Teste-os para ver o que é melhor para você. Algorítmos que permitem pouca distorção tendem a ser mais lentos. Então deve-se avaliar a performance versus qualidade.

Chegou ao ponto… eu não sei como fazer o algorítmo.
Tenho que fazer o que?
Primeiro pego a img? Faço o que com a imagem? imagem mesmo ou o endereço dela? Entende? API não é tutorial, API ajuda quando já sabemos alguns metodos, ou o que pelo menos temos que fazer, os procedimentos. Entende?

Olá Ellensmp,

Os algorítmos jão estão prontos. Sabe o parâmetro hints, do método getScaledInstance(int width, int height, int hints)? Nele você especifica um dos algorítmos disponíveis. Lendo a documentação, verifica-se que existem 5 possíveis: SCALE_AREA_AVERAGING, SCALE_DEFAULT, SCALE_FAST, SCALE_REPLICATE e SCALE_SMOOTH.

Primeiro pego a img? Faço o que com a imagem?

Na documentação existem especificados 9 possíveis construtores. Você escolherá o que melhor for para você. Num dos posts anteriores eu te mostrei dois exemplos (07/07/2010 - 17:52:15).

imagem mesmo ou o endereço dela?

Vejo o construtor que melhor se adapta ao seu caso. Existem as duas alternativas. Caso possua a imagem, clique )]aqui; Senão, aqui.

Entende? API não é tutorial, API ajuda quando já sabemos alguns metodos, ou o que pelo menos temos que fazer, os procedimentos. Entende?

Estou tentando lhe ajudar, mas não espere que eu escreva todo o seu código. Ler o javadoc e criá-lo para os seus projetos é muito importante. Aqui no fórum o pessoal vai te passar os caminhos possíveis, e uma das formas é informando a documentação a ser lida.

No seu caso, creio que seria interessante criar um método específico para redimensionamento de imagens. Esse método seria o responsável por retornar uma nova instância de uma imagem já redimensionada, conforme os parâmetros informados. Por exemplo:

/**
 * Retorna uma imagem com as dimensões especificadas.
 * @return Uma imagem.
 * @param byteData Um array de bytes representando o arquivo.
 * @param widthNew A nova largura da imagem.
 * @param heightNew A nova altura da imagem.
 */
private Image getImageScaled( final byte[] byteData, final int widthNew, final int heightNew ){
    ImageIcon icon = new ImageIcon( byteData );  
    Image image = icon.getImage();  

    return this.getImageScaled( image, widthNew, heightNew );
}//Fim do metodo

/**
 * Retorna uma imagem com as dimensões especificadas.
 * @return Uma imagem.
 * @param fileName O nome e endereço completo do arquivo (uma URI). Por exemplo: c:/imagem.jpg.
 * @param widthNew A nova largura da imagem.
 * @param heightNew A nova altura da imagem.
 */
private Image getImageScaled( final String fileName, final int widthNew, final int heightNew ){
    return this.getImageScaled( new URL( fileName ), widthNew, heightNew );
}//Fim do metodo

/**
 * Retorna uma imagem com as dimensões especificadas.
 * @return Uma imagem.
 * @param url Uma URL representando o endereço e nome completos do arquivo.
 * @param widthNew A nova largura da imagem.
 * @param heightNew A nova altura da imagem.
 */
private Image getImageScaled( final URL url, final int widthNew, final int heightNew ){
    ImageIcon icon = new ImageIcon( url );
    Image image = icon.getImage();  

    return this.getImageScaled( image, widthNew, heightNew );
}//Fim do metodo

/**
 * Retorna uma imagem com as dimensões especificadas.
 * @return Uma imagem.
 * @param imageOld A imagem a partir da qual será criada uma nova.
 * @param widthNew A nova largura da imagem.
 * @param heightNew A nova altura da imagem.
 */
private Image getImageScaled( final Image imageOld, final int widthNew, final int heightNew ){
    return imageOld.getScaledInstance( width, height, Image.SCALE_DEFAULT );  
}//Fim do metodo

Inté!

[quote=Eder Peixoto]Olá Ellensmp,

Os algorítmos jão estão prontos. Sabe o parâmetro hints, do método getScaledInstance(int width, int height, int hints)? Nele você especifica um dos algorítmos disponíveis. Lendo a documentação, verifica-se que existem 5 possíveis: SCALE_AREA_AVERAGING, SCALE_DEFAULT, SCALE_FAST, SCALE_REPLICATE e SCALE_SMOOTH.

Primeiro pego a img? Faço o que com a imagem?

Na documentação existem especificados 9 possíveis construtores. Você escolherá o que melhor for para você. Num dos posts anteriores eu te mostrei dois exemplos (07/07/2010 - 17:52:15).

imagem mesmo ou o endereço dela?

Vejo o construtor que melhor se adapta ao seu caso. Existem as duas alternativas. Caso possua a imagem, clique )]aqui; Senão, aqui.

Entende? API não é tutorial, API ajuda quando já sabemos alguns metodos, ou o que pelo menos temos que fazer, os procedimentos. Entende?

Estou tentando lhe ajudar, mas não espere que eu escreva todo o seu código. Ler o javadoc e criá-lo para os seus projetos é muito importante. Aqui no fórum o pessoal vai te passar os caminhos possíveis, e uma das formas é informando a documentação a ser lida.

No seu caso, creio que seria interessante criar um método específico para redimensionamento de imagens. Esse método seria o responsável por retornar uma nova instância de uma imagem já redimensionada, conforme os parâmetros informados. Por exemplo:

/**
 * Retorna uma imagem com as dimensões especificadas.
 * @return Uma imagem.
 * @param byteData Um array de bytes representando o arquivo.
 * @param widthNew A nova largura da imagem.
 * @param heightNew A nova altura da imagem.
 */
private Image getImageScaled( final byte[] byteData, final int widthNew, final int heightNew ){
    ImageIcon icon = new ImageIcon( byteData );  
    Image image = icon.getImage();  

    return this.getImageScaled( image, widthNew, heightNew );
}//Fim do metodo

/**
 * Retorna uma imagem com as dimensões especificadas.
 * @return Uma imagem.
 * @param fileName O nome e endereço completo do arquivo (uma URI). Por exemplo: c:/imagem.jpg.
 * @param widthNew A nova largura da imagem.
 * @param heightNew A nova altura da imagem.
 */
private Image getImageScaled( final String fileName, final int widthNew, final int heightNew ){
    return this.getImageScaled( new URL( fileName ), widthNew, heightNew );
}//Fim do metodo

/**
 * Retorna uma imagem com as dimensões especificadas.
 * @return Uma imagem.
 * @param url Uma URL representando o endereço e nome completos do arquivo.
 * @param widthNew A nova largura da imagem.
 * @param heightNew A nova altura da imagem.
 */
private Image getImageScaled( final URL url, final int widthNew, final int heightNew ){
    ImageIcon icon = new ImageIcon( url );
    Image image = icon.getImage();  

    return this.getImageScaled( image, widthNew, heightNew );
}//Fim do metodo

/**
 * Retorna uma imagem com as dimensões especificadas.
 * @return Uma imagem.
 * @param imageOld A imagem a partir da qual será criada uma nova.
 * @param widthNew A nova largura da imagem.
 * @param heightNew A nova altura da imagem.
 */
private Image getImageScaled( final Image imageOld, final int widthNew, final int heightNew ){
    return imageOld.getScaledInstance( width, height, Image.SCALE_DEFAULT );  
}//Fim do metodo

Inté![/quote]

Deixa eu ver se entendi… eu com a imagem que peguei, essa mesma imagem vai ser redimensionada dai vou ter 2 imagens ai eu gravo qual eu quero?

Isso mesmo.