Basicamente o código recebe o arquivo de origem, o destino, a largura e a altura máxima do thumbnail a ser gerado.
É tudo muito simples e requer apenas a biblioteca padrão awt do Java.
Primeiro vamos ler o arquivo de origem:
FileInputStream input = new FileInputStream(source); BufferedImage bufImage = ImageIO.read(input);
Agora precisamos calcular o scale, que será o índice para redimensionar a área da imagem. Se a altura original da imagem for maior, o scale será o resultado da divisão da altura do thumb pela altura original. E vice- versa.
double scale1 = (double) width / (double) bufImg.getWidth(); double scale2 = (double) height / (double) bufImg.getHeight(); double resultScale = scale1 > scale2 ? scale2 : scale1;
Utilizando o resultado obtido para o cálculo do redimensionamento:
int realWidth = bufImg.getWidth();
int realHeigth = bufImg.getHeight();
BufferedImage imageScaled = new BufferedImage((int) (
w * resultScale), (int) (h * resultScale),
BufferedImage.TYPE_INT_RGB);
Só o BufferedImage gerado não basta. É necessário, por fim, desenhar os gráficos da imagem novamente com os novos parâmetros calculados:
Graphics2D g2 = scaled.createGraphics();
g2.setComposite(AlphaComposite.Src);
g2.drawImage(img.getScaledInstance((int) (realWidth * resultScale),
(int) (realHeigth * resultScale), Image.SCALE_SMOOTH),
0, 0, (int) (w * resultScale), (int) (h * resultScale), null);
g2.dispose();
// Escrevendo no arquivo de sáida
ImageIO.write(imageScaled, "JPG", output);
Código completo:
public class ThumbGenerator {
public static boolean generate (File source, File dest,
int height, int width) throws IOException {
if (source != null && dest != null) {
FileInputStream input = new FileInputStream(source);
try {
BufferedImage bufImage = ImageIO.read(input);
if(bufImage != null) {
double scale = calcScale(bufImage, width, height);
BufferedImage imageScaled = scale(bufImage, scale);
FileOutputStream fos = new FileOutputStream(dest);
ImageIO.write(imageScaled, "JPG", fos);
fos.close();
input.close();
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
private static double calcScale(BufferedImage img,
int width, int height) {
double scale1 = (double) width / (double) img.getWidth();
double scale2 = (double) height / (double) img.getHeight();
double scale = scale1 > scale2 ? scale2 : scale1;
return scale;
}
private static BufferedImage scale(BufferedImage img,
double scale) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage scaled = new BufferedImage((int) (w * scale),
(int) (h * scale), BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = scaled.createGraphics();
g2.setComposite(AlphaComposite.Src);
g2.drawImage(img.getScaledInstance((int) (w * scale),
(int) (h * scale), Image.SCALE_SMOOTH),
0, 0, (int) (w * scale), (int) (h * scale), null);
g2.dispose();
return scaled;
}
}
Daí é só chamar:
ThumbGenerator.generate(imgSource, output, 400, 400); // Ver resultado no arquivo output ThumbGenerator.generate(imgSource, output, 400, 600); ThumbGenerator.generate(imgSource, output, 600, 400); ThumbGenerator.generate(imgSource, output, 100, 100);
3 comentários:
Interessante, farei um teste para ver se funciona bem!
Muito bom!
Para quem faz upload e não quer salvar o arquivo enviado uma dica interessante seria passar os bytes[] ao invés do "File source". Será que dá erro ou vai certinho?
Opa, ótima dica. Dá sim, só ia precisar trocar a chamada que cria o inputStream.
Em vez de ser FileInputStream recebendo um file, poderia ser um ByteArrayInputStream recebendo um array de bytes.
O método read do ImageIO recebe um objeto do tipo InputStream, então isso daria sim!
Postar um comentário