7

我想使用 Java 压缩 jpeg 文件。我这样做:

  1. 将图像读取为BufferedImage
  2. 将图像以压缩率写入另一个文件。

好的,这看起来很简单,但是我发现新文件中没有 ICC 颜色配置文件和 EXIF 信息,并且图像的 DPI 从 240 下降到 72。它看起来与原始图像不同。我在 OS X 中使用了预览之类的工具。它可以完美地改变图像的质量,而不会影响其他信息。

我可以用Java做到这一点吗?至少保留 ICC 颜色配置文件,让图像颜色看起来与原始照片相同?

4

2 回答 2

0

终于找到了一种方法来做到这一点。

使用 javax.imageio.IIOImage。它可以被 JpegImageReader 读取。

但是其中有一个bug,一个持续了6年的bug。:(

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4924909

幸运的是,如果你做了一些 hack(伪造 JFIF 部分),它就可以工作。:D

所以,这个问题可以这样解决:

  1. 使用 ImageIO 获取用于 jpeg 的 ImageReader
  2. 将 jpeg 图像读入内存缓冲区
  3. 如果它在错误 4924909 处失败,则使用伪造的 JFIF 信息修复图像缓冲区
  4. 使用 ImageWriter 写入文件,让 ImageWriterParam 来解决问题。

好吧,似乎没问题(保存的所有信息),除了一件事,输出图像比原始图像更亮(或者更确切地说,苍白)(当我使用 OS X 预览压缩照片时不会发生这种情况,所以问题一定出在我的代码或java中,或者我的错误用法:()。

所以,我在java中压缩jpeg的问题还没有解决。

有什么建议么?

于 2009-06-04T06:25:37.803 回答
0
/**
 * @param inputFilenameWithPath : binary filepath
 * @param outputFilepath        : output image path
 * @param start                 : from where the image start in binary file
 * @param len                   : length of the image
 * @throws ImageAccessException
 */
public void extractImageFromBinaryFile(String inputFilenameWithPath, String outputFilepath, int start, int len) throws ImageAccessException
{
    try
    {
        File file = new File(inputFilenameWithPath);
        FileImageInputStream iis = new FileImageInputStream(file);

        // Added
        byte[] b = new byte[start];
        iis.read(b, 0, start);

        byte[] fb = new byte[]{};
        iis.read(fb);

        IIOByteBuffer iiob = new IIOByteBuffer(fb, start, len);
        iis.readBytes(iiob, len);

        OutputStream os = new FileOutputStream(outputFilepath);
        os.write(iiob.getData());
        iis.close();
        os.close();

    }
    catch (IOException ioe)
    {`enter code here`
        throw new ImageAccessException("Image File read/write error");
    }
}
于 2012-11-28T06:19:34.463 回答