Alguem sabe como redimensionar uma imagem sem
distorcer ela
eu precisava colocar uma imagem maior em
um recipiente menor que a imagem
queria saber se tem com redimensionar a imagem para não distorcer
desde já agradeço
Defina ‘distorcer’.
Bom, vais precisar extender (ou estender?) um JComponent e sobrescrever o método paintComponent(Graphics g), de modo a desenhar a imagem. Para tal, será necessário usar um dos métodos drawImage de Graphics ou de Graphics2D.
Neste, é possível passar como parâmetro uma transformação a ser aplciada na imagem. Dessa forma, basta descobrir a largura atual do seu componente, com o método getBounds(Rectangle rv), e, sabendo o tamanho da sua imagem, calcular o fator de escala para usar na transformação apropriada no drawImage. Ver: AffineTransform e getScaleInstance(double sx, double sy) .
Mais detalhado do que isso só pagando. 8)
Apesar do jeito que o Furutani mostra parecer bem mais complicado, é necessário fazer desta forma e não usando o getScaledInstance, pois a performance deste é sofrível além de gastar muita memória.
Este exemplo funcionaria com formatos outros que não o JPEG, como PNG? Eu uso getScaledInstance, já havia lido sobre problemas de performance com ele e gostaria de fazer de outro jeito, mas se só funcionar com JPEG não resolve o problema que temos aqui.
tentei colocar isso para meu programa de captura de tela, mas a miniatura q consigo e uma tela preta alguem poderia me ajudar?
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
//import javax.swing.AbstractAction;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
//import java.awt.BorderLayout;
//import java.awt.Frame;
//import java.awt.event.ActionEvent;
//import java.awt.event.WindowAdapter;
//import java.awt.event.WindowEvent;
//import java.awt.event.WindowListener;
//import java.awt.Color;
//import java.awt.event.*;
public class ScreenShot2 extends java.applet.Applet implements Runnable {
Thread capturador;
int delay;
static Image imagem1;
public void init() {//coisa de applet
String str = getParameter("fps");
int fps = (str != null) ? Integer.parseInt(str) : 10;
delay = (fps > 0) ? (1000 / fps) : 100;
Toolkit t = Toolkit.getDefaultToolkit();
}
// o start da applet
public void start() {
capturador = new Thread(this);
capturador.start();//começa a correr a thread esse start eh do thread
}
@SuppressWarnings("deprecation")
public void atualiza(String arquivo){
//tempo de espera
String tempo = "0";//em milissegundo vezes um long mil abaixo para se tornarem segundos
try {
long time = Long.parseLong(tempo) * 1000L;
System.out.println("Waiting " + (time / 1000L) +
" second(s)...");
Thread.sleep(time);
} catch(NumberFormatException nfe) {
System.err.println(tempo + " does not seem to be a " +
"valid number of seconds.");
System.exit(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screenSize = toolkit.getScreenSize();
Rectangle screenRect = new Rectangle(screenSize);
// criar screenshot
Robot robot = null;
try {
robot = new Robot();
} catch (AWTException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
BufferedImage image = robot.createScreenCapture(screenRect);
imagem1=image;/*equivalencia pra imagem redimensionada creio ser aqui aonde está o erro povo*/
try {
ImageIO.write(image, "gif", new File(arquivo));
System.out.println("Arquivo gerado : "+arquivo);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/////////ABAIXO O Q ROBEI DESCARADAMENTE DO FRUTANI////////////
private void redimensionar(Image image, int width, int height, int quality,
String diretorio) {
// Calculos necessários para manter as propoçoes da imagem, conhecido
// como "aspect ratio"
double thumbRatio = (double) width / (double) height;
int imageWidth = image.getWidth(null);
int imageHeight = image.getHeight(null);
double imageRatio = (double) imageWidth / (double) imageHeight;
if (thumbRatio < imageRatio) {
height = (int) (width / imageRatio);
} else {
width = (int) (height * imageRatio);
}
// Fim do cálculo
BufferedImage thumbImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = thumbImage.createGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
BufferedOutputStream out;
try {
out = new BufferedOutputStream(new FileOutputStream(diretorio));
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder
.getDefaultJPEGEncodeParam(thumbImage);
quality = Math.max(0, Math.min(quality, 100));
param.setQuality((float) quality / 100.0f, false);
encoder.setJPEGEncodeParam(param);
encoder.encode(thumbImage);
out.close();
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException " + e.getMessage());
} catch (ImageFormatException e) {
System.out.println("ImageFormatException " + e.getMessage());
} catch (IOException e) {
System.out.println("IOException " + e.getMessage());
}
}
/////////////////////ACIMA ROUBO DESCARADO DO FRUTANI////////////
public void run() {for(int i = 0; i < 10; i++){//metodos da thread começados no start
new ScreenShot2().atualiza("c:/testea"+i+".gif");
redimensionar (imagem1,300,225,100,"c:/testeb"+i+".gif");
if (i>=9) {i=0;}}//Pra zerar td isso e recontinuar o loop
}
}
Pessoal,
Como eu poderia alterar o código do Furutani para que o método desta classe retorne um Image redimensionado?
Abraço,
Petrus.
Olá pessoal!
Desculpem-me por “ressuscitar” este tópico antigo.
Eu gostaria simplesmente de exibir uma imagem, e que ela fosse redimensionada automaticamente para o tamanho do componente. Em vb temos o Picture Box ou Image Box (se não me engano são esses os nomes) e nas propriedades do Image Box é possível definir a imagem em auto stretch. Existe algo similar em Java?
[quote=perfectron]Olá pessoal!
Desculpem-me por “ressuscitar” este tópico antigo.
Eu gostaria simplesmente de exibir uma imagem, e que ela fosse redimensionada automaticamente para o tamanho do componente. Em vb temos o Picture Box ou Image Box (se não me engano são esses os nomes) e nas propriedades do Image Box é possível definir a imagem em auto stretch. Existe algo similar em Java?[/quote]
bom…o que eu te indicaria é usa o getScaledInstance mesmo, se o que vc busca é uma opção “facil”…
tb não manjo mto de imagens, mais tenho aqui tela funcionando assim:
[code]BufferedImage fundo = null;
try{
fundo = ImageIO.read(new File(arquivoJPG));
}catch(java.io.IOException ioe){
System.out.println(“IO Error”);
fundo = new BufferedImage(1,1,BufferedImage.BITMASK );
}
Image imagem = fundo.getScaledInstance(65, 65, 1000) ;
ImageIcon jpg = new ImageIcon( imagem );
label.setIcon(jpg);[/code]
Obrigado maior_abandonado
Eu já tinha implementado exatamente dessa forma, mas pensei que pudesse existir algo mais simples, como simplesmente setar as propriedades de um componente.
Não é preguiça, mas só para saber se existe algo mais simples e não ter de “reinventar a roda”… hehehe
Abraço, e mais uma vez obrigado.
To com um problema semelhante, quando adicono a imagem elaredimenciona no meu Label porém ela fica Preta e Branco:
private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {
UIManager.put("FileChooser.lookInLabelMnemonic", new Integer('E'));
UIManager.put("FileChooser.lookInLabelText", "Examinar");
UIManager.put("FileChooser.saveInLabelText", "Salvar em");
UIManager.put("FileChooser.fileNameLabelMnemonic", new Integer('N')); // N
UIManager.put("FileChooser.fileNameLabelText", "Nome do arquivo");
UIManager.put("FileChooser.filesOfTypeLabelMnemonic", new Integer('T')); // T
UIManager.put("FileChooser.filesOfTypeLabelText", "Tipo");
UIManager.put("FileChooser.upFolderToolTipText", "Voltar");
UIManager.put("FileChooser.upFolderAccessibleName", "Voltar");
UIManager.put("FileChooser.homeFolderToolTipText", "Desktop");
UIManager.put("FileChooser.homeFolderAccessibleName", "Desktop");
UIManager.put("FileChooser.newFolderToolTipText", "Criar nova pasta");
UIManager.put("FileChooser.newFolderAccessibleName", "Criar nova pasta");
UIManager.put("FileChooser.listViewButtonToolTipText", "Lista");
UIManager.put("FileChooser.listViewButtonAccessibleName", "Lista");
UIManager.put("FileChooser.detailsViewButtonToolTipText", "Detalhes");
UIManager.put("FileChooser.detailsViewButtonAccessibleName", "Detalhes");
UIManager.put("FileChooser.fileNameHeaderText", "Nome");
UIManager.put("FileChooser.fileSizeHeaderText", "Tamanho");
UIManager.put("FileChooser.fileTypeHeaderText", "Tipo");
UIManager.put("FileChooser.fileDateHeaderText", "Data");
UIManager.put("FileChooser.fileAttrHeaderText", "Atributos");
JFileChooser fileChooser = new JFileChooser();
int result = fileChooser.showOpenDialog(null);
if(result == JFileChooser.CANCEL_OPTION){
} else{
try {
file = fileChooser.getSelectedFile().getPath();
File originalImage = new File(file);
File resizedFile = new File("C:/Users/Brambilla/Documents/NetBeansProjects/Pizzaria/teste/imagem"+campoNome.getText()+".jpg");
resize(originalImage, resizedFile, 101, 0.7f);
ImageIcon ar = new ImageIcon("C:/Users/Brambilla/Documents/NetBeansProjects/Pizzaria/teste/imagem"+campoNome.getText()+".jpg");
campoimagem.setIcon(ar);
} catch (IOException ex) {
Logger.getLogger(CadastroCliente.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Agora segue o metodo resize, que eu axo que é o que está fazendo isso com a imagem:
void resize(File originalFile, File resizedFile, int newWidth, float quality) throws IOException {
if (quality < 0 || quality > 1) {
throw new IllegalArgumentException("Quality has to be between 0 and 1");
}
ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
Image i = ii.getImage();
Image resizedImage = null;
int iWidth = i.getWidth(null);
int iHeight = i.getHeight(null);
resizedImage = i.getScaledInstance(110, 110, 110);
Image temp = new ImageIcon(resizedImage).getImage();
BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null),
BufferedImage.TYPE_INT_RGB);
Graphics g = bufferedImage.createGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
g.drawImage(temp, 0, 0, null);
g.dispose();
float softenFactor = 0.05f;
float[] softenArray = {0, softenFactor, 0, softenFactor, 1-(softenFactor*4), softenFactor, 0, softenFactor, 0};
Kernel kernel = new Kernel(3, 3, softenArray);
ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
bufferedImage = cOp.filter(bufferedImage, null);
FileOutputStream out = new FileOutputStream(resizedFile);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);
param.setQuality(quality, true);
encoder.setJPEGEncodeParam(param);
encoder.encode(bufferedImage);
}
[quote=brambilla9]To com um problema semelhante, quando adicono a imagem elaredimenciona no meu Label porém ela fica Preta e Branco:
[/quote]
Porque você não herda um bean como jlabel e implementa esse codigo? O resultado será semelhante ao pic box.
Se você poder me ajudar a fazer, pq eu nunca fiz isso
se a imagem está preta acredito que é porque seu código não identificou o arquivo de origem ou o metodo ‘redimensionar’ não recebeu o ‘image’ de forma correta.
vai debugando e vendo se estas variáveis estão setadas corretamente…
[]'s