2009-06-04 79 views
7

我想使用Java压缩jpeg文件。我不喜欢这样写道:如何在Java中压缩jpeg图像而不丢失该图像中的任何元数据?

  1. 读取图像BufferedImage
  2. 图像写入与压缩率的另一个文件。

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

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

回答

1
/** 
* @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"); 
    } 
} 
+0

请解释你的代码。 – hims056 2012-11-28 06:39:34

0

最后找到一种方法来做到这一点。

使用javax.imageio.IIOImage。它可以由JpegImageReader提供。

但它有一个bug,一个bug持续了6年。 :(

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

幸运的是,如果你做一些黑客攻击(假冒JFIF部分),以及它的工作原理:d

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

  1. 使用ImageIO获取JPEG图像读取器
  2. 将JPEG图像读入内存缓冲区
  3. 如果在错误4924909时失败,则修复图像buf用假的JFIF信息传送
  4. 使用ImageWriter来写入文件,让ImageWriterParam去做。

好吧,它似乎是好的(每一个信息保存),除了一件事情,输出图像比原始图像更明亮(或者说,苍白)(当我使用预览时不会发生OS X到压缩照片,这样的问题必须在我的代码或Java,还是我错用法:()。

所以,我压缩在Java中的jpeg问题尚未解决。

任何建议?

+0

好吧,我放弃了。ImageIO无法正常工作(在至少对我来说)。我只是想改变图像的质量来压缩它,而不会丢失任何信息,并且看起来与原始照片相同。 Java失败了,我打算使用ImageMagic和JNI来做到这一点。 也许我错了。任何来自oracle的人都可以帮忙 – guitarpoet 2009-06-04 10:30:24