java - 合并两个图像 --> 4 倍大小!如何减小文件大小?

标签 java image-processing graphics merge bufferedimage

我使用下面的代码合并两个图像。一张不透明的基础图像,一张透明的覆盖图像。 其拥有的图像文件大小分别为 20kb 和 5kb。 合并两个图像后,生成的文件大小 > 100kb,因此至少是 25kb 组合大小的 4 倍。我预计文件大小小于 25kb。

public static void mergeTwoImages(BufferedImage base, BufferedImage overlay, String destPath, String imageName) {

    // create the new image, canvas size is the max. of both image sizes
    int w = Math.max(base.getWidth(), overlay.getWidth());
    int h = Math.max(base.getHeight(), overlay.getHeight());
    BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

    // paint both images, preserving the alpha channels
    Graphics2D g2 = combined.createGraphics();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.drawImage(base, 0, 0, null );
    g2.drawImage(overlay, 0, 0, null);
    g2.dispose();

    // Save as new image
    saveImage(combined, destPath + "/" + imageName + "_merged.png");
}

我的应用程序必须具有非常好的性能,因此任何人都可以解释为什么会发生这种效果以及如何减少生成的文件大小?

非常感谢!

编辑: 非常感谢你的回答。保存图像代码为:

public static void saveImage(BufferedImage src, String file) {
    try {
        File outputfile = new File(file);
        ImageIO.write(src, "png", outputfile);
    } catch (IOException e) {
        e.printStackTrace();
    }       
}

最佳答案

因为PNG是一种无损格式,只有两个主要因素可能影响文件大小:

  1. 文件中有多少像素,以及
  2. 该格式的压缩效果如何。

因为听起来你正在做叠加,所以我猜 #1 没有改变。比较输入和输出文件的像素尺寸以仔细检查。

您遇到问题很可能是因为您的合并图像更加复杂,因此 PNG 过滤算法更难压缩文件。除了更改图像或切换到有损文件格式之外,您对此无能为力。

为了进一步解释一下,假设您有一张全白图像和一张全红色图像。两者都是 100x100 像素。这些图像非常容易压缩,因为您只需要编码:重复 red 10000 次。现在,假设您以每个其他像素都来自不同图像的方式合并这些图像。现在是方格的。如果您设置了良好的编码机制,您仍然可以通过说:重复 [red,white] 10000 次来很好地编码。但您会注意到,即使使用这种理想的编码算法,我也将编码消息的大小增加了很多。如果您没有一种非常适合此类事情的编码格式,那么一切都会从那里开始走下坡路。

一般来说,图像的像素相互之间越多样化、越随机,生成的文件就越大。

关于java - 合并两个图像 --> 4 倍大小!如何减小文件大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11349378/

相关文章:

java - 关闭时未删除临时文件

java - Java 中 Class.getConstructors() 返回的数组顺序如何

matlab - matlab中图像的直方图拉伸(stretch)

math - 使用贝塞尔曲线的圆近似

iphone - 性能方面 : A lot of small PNGs or one large PNG?

c# - 我可以避免 FillPolygon 与 DrawPolygon 的错误/不同渲染吗?

java - 使用 Spring Boot 配置 Ehcache TTL 超时

java - 无法在 Java 中启动 Tomcat

javascript - 如何在 React Native 中裁剪图像,使其看起来像圆形而不是矩形?

c# - 如何使用 OpenCVSharp 将 Mat 转换为 Bitmap?