图片压缩通常涉及减少图片的尺寸(缩放)、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等。

 使用Java内置的图像IO库

Java的javax.imageio包提供了基本的图像IO功能,但它不直接支持压缩质量的调整。然而,你可以通过缩放图片来间接实现压缩。

这种方法无疑是最简单的,但是会减少图片尺寸 

import javax.imageio.ImageIO;  
import java.awt.Graphics2D;  
import java.awt.Image;  
import java.awt.RenderingHints;  
import java.awt.image.BufferedImage;  
import java.io.File;  
import java.io.IOException;  
  
public class ImageUtils {  
  
    /**  
     * 生成缩略图  
     *  
     * @param oldPath     原文件路径  
     * @param newPath     缩略图文件路径  
     * @param smallFactor 缩略图缩放因子(例如,0.5表示缩小到一半)  
     * @return 是否成功生成缩略图  
     */  
    public static boolean generateThumbnail(String oldPath, String newPath, double smallFactor) {  
        try (FileInputStream fis = new FileInputStream(oldPath)) {  
            BufferedImage originalImage = ImageIO.read(fis);  
            if (originalImage == null) {  
                System.err.println("Failed to read the original image: " + oldPath);  
                return false;  
            }  
  
            int width = originalImage.getWidth();  
            int height = originalImage.getHeight();  
            int thumbnailWidth = (int) (width * smallFactor);  
            int thumbnailHeight = (int) (height * smallFactor);  
  
            BufferedImage thumbnail = new BufferedImage(thumbnailWidth, thumbnailHeight, BufferedImage.TYPE_INT_RGB);  
            Graphics2D g2d = thumbnail.createGraphics();  
  
            // 设置高质量的插值方法  
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);  
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);  
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);  
  
            g2d.drawImage(originalImage, 0, 0, thumbnailWidth, thumbnailHeight, null);  
            g2d.dispose();  
  
            ImageIO.write(thumbnail, "jpg", new File(newPath));  
            return true;  
        } catch (IOException e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
  
    // ... 其他代码 ...  
}

 

使用ImageWriter和ImageWriteParam

对于JPEG图片,你可以使用ImageWriterImageWriteParam来设置压缩质量。

 下面是一个示例:

import javax.imageio.ImageIO;  
import javax.imageio.ImageWriteParam;  
import javax.imageio.ImageWriter;  
import javax.imageio.stream.ImageOutputStream;  
import java.awt.image.BufferedImage;  
import java.io.File;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.util.Iterator;  
  
/**
     * 图片压缩
     *
     * @param oldPath 原文件路径
     * @param newPath 压缩后路径
     */
public class ImageCompressor {  
  
    public static void compressImage(String srcFilePath, String destFilePath, float quality) throws IOException {  
        File input = new File(srcFilePath);  
        BufferedImage image = ImageIO.read(input);  
  
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");  
        ImageWriter writer = (ImageWriter) writers.next();  
  
        try (ImageOutputStream ios = ImageIO.createImageOutputStream(new FileOutputStream(destFilePath))) {  
            writer.setOutput(ios);  
  
            ImageWriteParam param = writer.getDefaultWriteParam();  
  
            // 设置压缩模式为MODE_EXPLICIT  
            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);  
  
            // 设置压缩质量,0.0 - 1.0之间  
            param.setCompressionQuality(quality);  
  
            writer.write(null, new IIOImage(image, null, null), param);  
        } finally {  
            writer.dispose();  
        }  
    }  
  
    public static void main(String[] args) {  
        try {  
            compressImage("path_to_source_image.jpg", "path_to_compressed_image.jpg", 0.5f);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}

 注意:

在图片压缩中,压缩质量(Compression Quality)是一个参数,用于控制图片在压缩过程中损失多少信息,以便在保持一定视觉质量的同时减小文件大小。压缩质量通常以一个浮点数表示,范围通常从0.0(最低质量,最大压缩)到1.0(最高质量,最小压缩或无损压缩,但这对于大多数有损压缩格式如JPEG来说并不适用,因为即使设置为1.0,JPEG仍然是有损的)。

对于JPEG格式的图片来说,压缩质量参数决定了在编码过程中如何平衡文件大小和图像质量。较低的压缩质量值会导致更多的信息被丢弃,从而产生更小的文件但更差的图像质量。相反,较高的压缩质量值会保留更多的图像细节,但文件会更大。

param.setCompressionQuality(quality); 这行代码设置了JPEG图片的压缩质量。quality 参数应该是一个在0.0和1.0之间的浮点数。可以根据需要调整这个值,以在文件大小和图像质量之间找到最佳平衡。

请注意,即使设置了最高的压缩质量(1.0),由于JPEG是有损压缩格式,所以原始图像和压缩后的图像之间仍然会存在一些细微的差异。对于需要完全保留原始图像数据的场景,应该使用无损压缩格式,如PNG或TIFF。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐