Как я могу сжать изображения JPEG в Java без потери метаданных в этом изображении? - PullRequest
7 голосов
/ 04 июня 2009

Я хочу сжать файлы JPEG с использованием Java. Я делаю это так:

  1. Прочитать изображение как BufferedImage
  2. Запишите изображение в другой файл с коэффициентом сжатия.

ОК, это кажется простым, но я считаю, что цветовой профиль ICC и информация EXIF ​​ушли в новый файл, а DPI изображения уменьшено с 240 до 72. Это выглядит иначе, чем исходное изображение. Я использую такой инструмент, как предварительный просмотр в OS X. Он может идеально изменить качество изображения, не затрагивая другую информацию.

Можно ли сделать это на Java? По крайней мере, сохранить цветовой профиль ICC и позволить цвету изображения выглядеть так же, как исходная фотография?

Ответы [ 2 ]

0 голосов
/ 28 ноября 2012
/**
 * @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 голосов
/ 04 июня 2009

Наконец-то найдите способ сделать это.

Используйте javax.imageio.IIOImage. Его можно прочитать с помощью JpegImageReader.

Но в нем была ошибка, ошибка длилась 6 лет. (

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

К счастью, если вы сделаете какой-нибудь хак (подделка раздела JFIF), и это сработает. : D

Итак, эту проблему можно решить следующим образом:

  1. Используйте ImageIO, чтобы получить ImageReader для JPEG
  2. Считать изображение JPEG в буфер памяти.
  3. Если при ошибке 4924909 произойдет ошибка, исправьте буфер изображения с ложной информацией JFIF
  4. Используйте ImageWriter для записи файла, позвольте ImageWriterParam сделать свое дело.

Что ж, похоже, все в порядке (каждая информация сохранена), за исключением одного, выходное изображение ярче (или, точнее, бледно), чем исходное изображение (этого не произойдет, если я использую предварительный просмотр OS X к сжатой фотографии, поэтому проблема должна быть в моем коде или Java, или мое неправильное использование :().

Итак, моя проблема сжатия jpeg в java еще не решена.

Есть предложения?

...