public class ImageUtils { private Image srcImage = null; private File srcFile = null; private File destFile = null; private String fileSuffix = null; private int imageWidth = 0; private int imageHeight = 0; public ImageUtils(String fileName) throws IOException { this(new File(fileName)); } public ImageUtils(File fileName) throws IOException { File _file = fileName; _file.setReadOnly(); this.srcFile = _file; this.fileSuffix = _file.getName().substring( (_file.getName().indexOf(".") + 1), (_file.getName().length())); this.destFile = new File(this.srcFile.getPath().substring(0, (this.srcFile.getPath().lastIndexOf("."))) + PIC_TEMPORARY + "." + this.fileSuffix); srcImage = javax.imageio.ImageIO.read(_file); //得到图片的原始大小, 以便按比例压缩。 imageWidth = srcImage.getWidth(null); imageHeight = srcImage.getHeight(null); System.out.println("width: " + imageWidth); System.out.println("height: " + imageHeight); } /** * 强制压缩/放大图片到固定的大小 * @param w int 新宽度 * @param h int 新高度 * @throws IOException */ public void resize(int w, int h) throws IOException { //得到合适的压缩大小,按比例。 if ( imageWidth >= imageHeight) { w = w; h = (int)Math.round((imageHeight * w * 1.0 / imageWidth)); } else { h = h; w = (int)Math.round((imageWidth * h * 1.0 / imageHeight)); } //构建图片对象 BufferedImage _image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); //绘制缩小后的图 _image.getGraphics().drawImage(srcImage, 0, 0, w, h, null); //输出到文件流 FileOutputStream out = new FileOutputStream(destFile); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(_image); out.flush(); out.close(); } }
下边是另外一种模式,不过原理都是一样的,就是等比例压缩,比较原图的宽高来确定压缩的比例。
Java中图片的缩放(按比例)
现在的一些应用中,我们常常需要把原始图片存到数据库中去,而显示的时候可能是各种缩小后的图片(长宽比例不变,不然图片会变形)。比如图片管理的时候先显示一系列小图片,点击后显示放大的图片。但是现在的图片有的height>width,而有的height<width,长宽比例个不相同,当显示一系列小图片的时候可能不整齐,一般网页上的方法是用固定的正方形做底色,然后在上面显示缩小后的图片。下面的resizeImage方法正是此问题的solution,输入参数maxDim就是固定的正方形的长度:
此外,此方法的类需要:
import com.sun.jimi.core.raster.JimiRasterImage;
import com.sun.jimi.core.Jimi;
/** resize the image in byte stream(format: [in]GIF, JPG; [out]JPG) * @param in - the binary stream of the original picture in GIF or JPG * @param maxDim - the bigger one between height and width after the picture is resized * @return the binary stream of the resized picture in JPG */ public static byte[] resizeImage(byte[] in,int maxDim) { try { Image inImage=Toolkit.getDefaultToolkit().createImage(in); ImageIcon inImageIcon = new ImageIcon(in); int imh = inImageIcon.getIconHeight(); int imw = inImageIcon.getIconWidth(); double scale; if( imh <= maxDim && imw <= maxDim ) scale = 1; else if( imh > imw ) scale = (double) maxDim / (double) imh; else scale = (double) maxDim / (double) imw; int scaledW = (int) (scale * imw); int scaledH = (int) (scale * imh); Image img = inImage.getScaledInstance(scaledW, scaledH, Image.SCALE_FAST); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); JimiRasterImage raster = Jimi.createRasterImage(img.getSource()); // --java.io.ByteArrayOutputStream Jimi.putImage("image/jpeg", raster, outStream); outStream.flush(); outStream.close(); return outStream.toByteArray(); } catch(Exception ex) { ex.printStackTrace(); return null; } }