7

Javaを使用してjpegファイルを圧縮したい。私はこのようにします:

  1. 画像を次のように読みますBufferedImage
  2. 圧縮率で画像を別のファイルに書き込みます。

簡単そうに見えますが、ICCカラープロファイルとEXIF情報が新しいファイルに削除され、画像のDPIが240から72に削除されています。元の画像とは異なって見えます。OS Xでプレビューのようなツールを使用しています。他の情報に影響を与えることなく、画像の品質を完全に変更できます。

これをJavaで実行できますか?少なくともICCカラープロファイルを維持し、画像の色を元の写真と同じに見せますか?

4

2 に答える 2

0

最後に、これを行う方法を見つけます。

javax.imageio.IIOImageを使用します。JpegImageReaderで読み取ることができます。

しかし、そこにはバグがあり、バグは6年間続きました。:(

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

幸いなことに、ハック(JFIFセクションを偽造)を行うと、機能します。:D

したがって、この問題は次のように解決できます。

  1. ImageIOを使用してjpegのImageReaderを取得します
  2. jpeg画像をメモリバッファに読み込みます
  3. バグ4924909で失敗した場合は、偽のJFIF情報で画像バッファを修正してください
  4. ImageWriterを使用してファイルを書き込み、ImageWriterParamにトリックを実行させます。

さて、それは大丈夫のようです(すべての情報が保存されています)、1つのことを除いて、出力画像は元の画像よりも明るい(またはむしろ薄い)(OSXのプレビューを圧縮写真に使用すると発生しません) 、したがって、問題は私のコードまたは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 に答える