2

我使用下面的代码合并两个图像。一张没有透明度的基本图像,一张有透明度的叠加图像。他们拥有的图像的文件大小分别为 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");
}

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

非常感谢!

编辑:非常感谢您的回答。saveImage 代码是:

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

2 回答 2

2

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

  1. 文件中有多少像素,以及
  2. 格式的压缩程度。

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

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

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

通常,图像的像素越多变化越随机,与其他像素相比,生成的文件就越大。

于 2012-07-05T17:50:31.443 回答
0

将图像另存为 JPEG,压缩率更高/质量更低。有关详细信息,请参阅:

于 2012-07-05T17:59:43.327 回答