Quem aqui nunca precisou pegar uma imagem de 2000x1800 e colocar em um espaço de 500x500? É exatamente esse problema que esse post vem resolver. Na verdade, precisamos fazer um calculo ninja jedi para conseguir escalar a imagem.
Esse calculo consiste em:
- Descobrir o que é menor na imagem, se é a altura ou a largura.
- Caso existir um lado menor, descobir seu percentual em relação ao lado maior.
- Agora em cima do espaço disponível (500x500)temos que tirar o percentual calculado anteriormente do menor lado da imagem.
Se a imagem já tiver altura igual a largura, nada será feito.
Então aqui está ele, o calculo, pronto para uso.
class ImageResizerService { public byte[] read(String file) { byte[] buffer = new byte[1024]; InputStream is = new FileInputStream(file); ByteArrayOutputStream out = new ByteArrayOutputStream(); while (is.read(buffer) != -1) { out.write(buffer); } try { return out.toByteArray(); }finally { is.close() out.close() } } public byte[] read(String file, double requiredWidth, double requiredHeight) { BufferedImage imagem = ImageIO.read(new File(file)); double originalWidth = imagem.getWidth(); double originalHeight = imagem.getHeight(); double newWidth = 0; double newHeight = 0; double diff = 0; if (requiredHeight == 0) { requiredHeight = requiredWidth; } if (requiredWidth == 0) { requiredWidth = requiredHeight; } if(originalWidth < requiredWidth && originalHeight < requiredHeight){ return read(file) } if(requiredWidth == 0 && requiredHeight == 0){ return read(file) } if (originalWidth > originalHeight) { diff = originalWidth - originalHeight; newWidth = requiredWidth; diff = diff / originalWidth; newHeight = newWidth - (newWidth * diff); } else if (originalWidth < originalHeight) { diff = originalHeight - originalWidth; newHeight = requiredHeight; diff = diff / originalHeight; newWidth = newHeight - (newHeight * diff); } else { if (requiredHeight > requiredWidth) { requiredHeight = requiredWidth; } else if (requiredHeight < requiredWidth) { requiredWidth = requiredHeight; } newHeight = requiredHeight; newWidth = requiredWidth; } int type = BufferedImage.TYPE_INT_RGB; boolean isPng = file.toUpperCase().endsWith("PNG") if (isPng) { type = BufferedImage.BITMASK; } BufferedImage new_img = new BufferedImage((int) newWidth, (int) newHeight, type); Graphics2D g = new_img.createGraphics(); g.setComposite(AlphaComposite.Src); g.drawImage(imagem, 0, 0, (int) newWidth, (int) newHeight, null); ByteArrayOutputStream out = new ByteArrayOutputStream(); if (isPng) { ImageIO.write(new_img, "PNG", out); }else{ ImageIO.write(new_img, "JPG", out); } try { return out.toByteArray(); } finally { out.close(); } } }
Se esse é o melhor ou mais fácil algoritimo não sei, desenvolvi ele apartir da minha necessidade, e até o momento não tive problemas com "deformação" de imagens. Ah, e notem que caso seja solicitada uma um tamanho maior do que o tamanho da imagem existente, ele não faz nada, pois o objetivo é não perder a qualidade da imagem. E caso o tamanho solicitado seja menor do que a imagem existente mas não obedeça suas proporções, ele manterá a proporção, não obedecendo as medidas silicitadas, sempre nivelando por um dos valores (altura ou largura). Nesse caso, pomos sempre passar ou só largura, ou só altura.
Até a próxima!
Obrigado por compartilhar
ResponderExcluirExcelente algoritmo, deu certinho
ResponderExcluirMuito obrigado por compartilhar!