1.纯三方库压缩png图片,效率稍微慢一点,但比java自带的会清晰一些

需要引入的pom文件

 		<!-- 图片压缩-->
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.20</version>
        </dependency>
        <!-- 注意:高版本 OpenViewerFX 可能移除了 PngCompressor,需使用特定版本如 6.6.14 -->
        <dependency>
            <groupId>org.jpedal</groupId>
            <artifactId>OpenViewerFX</artifactId>
            <version>6.6.14</version>
        </dependency>

java代码

   				 // 使用 Thumbnails 进行初步处理,设置图像类型以防止PNG背景问题
            BufferedImage bufferedImage = Thumbnails.of(file)
                    .scale(1) // 保持原始尺寸
                    .imageType(BufferedImage.TYPE_INT_ARGB) // 重要:针对PNG的设置
                    .asBufferedImage();
            // 临时保存Thumbnails处理后的图像
            File tempFile = File.createTempFile("temp", ".png");
            ImageIO.write(bufferedImage, "png", tempFile);
            // 使用 OpenViewerFX 的 PngCompressor 进行进一步压缩
            // 注意:PngCompressor.compress 方法的使用可能因版本而异,此处为示例
            File outputFile =  new File("C:\\Users\\18833\\Desktop\\fsdownload\\转换后\\"+file.getName());
            PngCompressor.compress(tempFile, outputFile); 
            // 清理临时文件
            tempFile.delete();

2.从新裁剪尺寸

 /**
     * 重新裁剪尺寸
     *
     * @param inputPath   输入图片地址
     * @param outputPath  输出图片地址
     * @param targetWidth 预期宽度(高度会根据比例自动调整)
     * @throws IOException
     */
    public static void resizeImage(String inputPath, String outputPath,
                                   int targetWidth) throws IOException {
        // 读取原始图片
        File inputFile = new File(inputPath);
        BufferedImage originalImage = ImageIO.read(inputFile);
        // 计算等比例缩放后的高度(如果只指定了宽度或高度)
        double aspectRatio = (double) originalImage.getHeight() / originalImage.getWidth();
        int targetHeight = (int) (targetWidth * aspectRatio);
        // 创建缩放后的图片
        Image scaledImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH);
        BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_ARGB);
        // 绘制缩放后的图片
        Graphics2D g2d = outputImage.createGraphics();
        g2d.drawImage(scaledImage, 0, 0, null);
        g2d.dispose();
        // 写入输出文件
        ImageIO.write(outputImage, "png", new File(outputPath));
    }

3.转换图片类型

这里使用了一个第三方库
 <dependency>
            <groupId>org.sejda.imageio</groupId>
            <artifactId>webp-imageio</artifactId>
            <version>0.1.6</version>
        </dependency>
 // 读取 PNG
            BufferedImage input = ImageIO.read(new File(reSizePngPath));
            // 找到 WebP 的 writer
            Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("webp");
            if (!writers.hasNext()) {
                throw new IllegalStateException("没有找到 WebP ImageWriter,请确认依赖已导入!");
            }
            ImageWriter writer = writers.next();
            // 设置压缩参数
            ImageWriteParam param = writer.getDefaultWriteParam();
            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置有损压缩模式
            param.setCompressionType("Lossy");        // 有损压缩类型
            param.setCompressionQuality(0.5f); // 0.0 ~ 1.0, 越低体积越小
            // 输出 WebP
            try (FileOutputStream fos = new FileOutputStream(outPutPath);
                 ImageOutputStream ios = ImageIO.createImageOutputStream(fos)) {
                writer.setOutput(ios);
                writer.write(null, new javax.imageio.IIOImage(input, null, null), param);
            }
            writer.dispose();

总结

我试了第一种方式我一个1.5M的图片保持原画质压缩到了700k,压缩下去一半。后来考虑了一下我们是要做成一个动态的视频而且我的图片大小在6000*5000左右太高清对我也没有那么大需求,所以是用了2+3的方案,图片压缩成了200K。
关于图片格式问题,ds给的答案
在这里插入图片描述

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐