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