java服務器圖片壓縮的幾種方式及效率比較


以下是測試了三種圖片壓縮方式,通過測試發現使用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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM