以下是測試了三種圖片壓縮方式,通過測試發現使用jdk的ImageIO壓縮時間更短,使用Google的thumbnailator更簡單,但是thumbnailator在GitHub上的源碼已經停止維護了。
1、Google的thumbnailator
pom.xml中引入依賴
<dependency> <groupId>net.coobird</groupId> <artifactId>thumbnailator</artifactId> <version>0.4.8</version> </dependency>
測試源碼:
/** * @Title: ThumbnailatorUtil * @Package: com.test.image * @Description: google Thumbnailator 測試 * @Author: monkjavaer * @Data: 2019/2/22 14:07 * @Version: V1.0 */ public class ThumbnailatorUtil { public static void main(String[] args) { try { long start = System.nanoTime(); compressPic(); long end = System.nanoTime(); System.out.println("壓縮時間:"+(end-start)*0.000000001+"s"); } catch (IOException e) { e.printStackTrace(); } } /** * scale: 按比例 * outputQuality:輸出的圖片質量,范圍:0.0~1.0,1為最高質量。注意使用該方法時輸出的圖片格式必須為jpg * @throws IOException */ public static void compressPic() throws IOException { // Thumbnails.of("E:\\3.png") Thumbnails.of("E:\\154.jpg") .scale(1f) .outputQuality(0.25f) .toFile("E:\\1.jpg"); } }
輸出:壓縮時間:0.5615769580000001s
2、Java原生ImageIO實現:
/** * @Title: ImageIOUtil * @Package: com.test.image * @Description: ImageIO test * @Author: monkjavaer * @Data: 2019/2/22 16:37 * @Version: V1.0 */ public class ImageIOUtil { public static void main(String[] args) throws IOException { long start = System.nanoTime(); compressPic("E:\\154.jpg", "E:\\1.jpg", 0.25f); long end = System.nanoTime(); System.out.println("壓縮時間:" + (end - start) * 0.000000001 + "s"); } public static void compressPic(String srcFilePath, String descFilePath, Float quality) throws IOException { File input = new File(srcFilePath); BufferedImage image = ImageIO.read(input); // 指定寫圖片的方式為 jpg ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); // 先指定Output,才能調用writer.write方法 File output = new File(descFilePath); OutputStream out = new FileOutputStream(output); ImageOutputStream ios = ImageIO.createImageOutputStream(out); writer.setOutput(ios); ImageWriteParam param = writer.getDefaultWriteParam(); if (param.canWriteCompressed()){ // 指定壓縮方式為MODE_EXPLICIT param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 壓縮程度,參數qality是取值0~1范圍內 param.setCompressionQuality(quality); } // 調用write方法,向輸入流寫圖片 writer.write(null, new IIOImage(image, null, null), param); out.close(); ios.close(); writer.dispose(); } }
輸出:壓縮時間:0.44548557000000005s
3、com.sun.image.codec.jpeg.JPEGCodec實現
測試代碼:
public class JPEGCodecUtil { public static void main(String[] args) throws IOException { long start = System.nanoTime(); compressPic(new File("E:\\154.jpg"), new File("E:\\1.jpg"), 1920, 0.25f); long end = System.nanoTime(); System.out.println("壓縮時間:" + (end - start) * 0.000000001 + "s"); } /** * 縮放圖片(壓縮圖片質量,改變圖片尺寸) * 若原圖寬度小於新寬度,則寬度不變! * @param newWidth 新的寬度 * @param quality 圖片質量參數 0.7f 相當於70%質量 * 2015年12月11日 */ public static void compressPic(File originalFile, File resizedFile, int newWidth, float quality) throws IOException { if (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); if(iWidth < newWidth){ newWidth = iWidth; } if (iWidth > iHeight) { resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH); } else { resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH); } // This code ensures that all the pixels in the image are loaded. Image temp = new ImageIcon(resizedImage).getImage(); // Create the buffered image. BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB); // Copy image to buffered image. Graphics g = bufferedImage.createGraphics(); // Clear background and paint the image. g.setColor(Color.white); g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null)); g.drawImage(temp, 0, 0, null); g.dispose(); // Soften. 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); // Write the jpeg to a file. FileOutputStream out = new FileOutputStream(resizedFile); // Encodes image as a JPEG data stream JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); JPEGEncodeParam param = encoder .getDefaultJPEGEncodeParam(bufferedImage); param.setQuality(quality, true); encoder.setJPEGEncodeParam(param); encoder.encode(bufferedImage); } // Example usage }
輸出:壓縮時間:0.52596054s