Java 1.5.0_16 испортил цвета при сохранении изображения jpg

у меня есть загруженное изображение с диска (сохраненное как BufferedImage), которое я правильно отображаю на JPanel, но когда я пытаюсь повторно сохранить это изображение с помощью приведенной ниже команды, изображение сохраняется в красноватом оттенке.

ImageIO.write(image, "jpg", fileName);

Примечание! изображение — это BufferedImage, а fileName — это объект File, указывающий на имя файла, которое будет сохранено и заканчивается на «.jpg».

Я читал, что были проблемы с методами ImageIO в более ранних JDK, но, насколько мне удалось найти, я не использую ни одну из этих версий. То, что я ищу, - это способ исправить эту проблему без обновления JDK, однако, сказав, что я все равно хотел бы знать, в каком JDK эта проблема была исправлена ​​(если это действительно ошибка с JDK, который я использую ).

Спасибо.


person Coder    schedule 02.05.2010    source источник
comment
Хорошо, я нашел еще немного информации. Я попытался сохранить изображение в формате png, и цвета были правильными. Так что кодировщик jpg кажется неправильным. Для меня очень важно сохранить изображение в формате jpg, так как файлы png имеют большой размер. У кого-нибудь есть дополнительная информация? Может быть, есть другой механизм сохранения изображения в виде файла jpg, возможно, через Toolkit?   -  person Coder    schedule 02.05.2010


Ответы (3)


Хорошо, решил мою проблему, кажется, мне нужно преобразовать изображение в BufferedImage.TYPE_INT_RGB по какой-то причине. Я думаю, что альфа-каналы могут неправильно обрабатываться на каком-то уровне.

person Coder    schedule 02.05.2010
comment
Приятно слышать, что вы нашли решение. Как вы знаете, я предлагал изменить тип буферизованного изображения в своем ответе, но, не зная специфики вашего изображения, я не мог с уверенностью сказать, какой тип изображения будет работать. - person mdma; 03.05.2010
comment
Да точно, еще раз спасибо. Я не уверен, как работает вся эта система голосования (я новичок на этом форуме), если это то, что вы предлагаете, но за ваш ответ назначен один балл. Я не знаю, какое подходящее место для этого, но это кажется уместным разместить здесь. Как я уже сказал, я только что присоединился, но пока что я действительно впечатлен тем, насколько вежливым и отзывчивым является это сообщество. Приятно быть частью этого. - person Coder; 03.05.2010
comment
+1 за полезный отзыв. Я призываю вас принять ответ @mdma, поскольку он впервые выявил основную проблему. Конечно, вы также можете проголосовать за любой ответ, который вы считаете полезным. - person trashgod; 03.05.2010

Я бы сначала начал с изучения того, является ли проблема цветовой моделью BifferedImage или кодировкой jpeg. Вы можете попробовать изменить тип изображения (третий аргумент в конструктор), чтобы увидеть, производит ли это разницу, а также напрямую использовать JPEGCodec для сохранения jpeg.

E.g.

 BufferedImage bufferedImage = ...;  // your image
 out = new FileOutputStream ( filename );
 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder ( out );
 JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam ( bufferedImage );
 encoder.setJPEGEncodeParam ( param );
 encoder.encode ( bufferedImage );
 out.close();

РЕДАКТИРОВАТЬ: изменен текст, это тип изображения, который вы хотите изменить. Смотрите ссылку на конструктор.

person mdma    schedule 02.05.2010
comment
Спасибо за предложение. не могли бы вы предоставить некоторые фрагменты кода, пожалуйста? Если, используя кодек напрямую, вы имеете в виду Iterator Writers = ImageIO.getImageWritersBySuffix(jpeg);, то я уже пробовал это, и это то же самое поведение. - person Coder; 02.05.2010
comment
Я имею в виду использование кодека, используя приведенный выше фрагмент, чтобы сохранить изображение в формате JPEG. - person mdma; 02.05.2010
comment
Еще раз спасибо, я попробовал то, что вы предложили (точно скопировал ваш код), и у меня такое же поведение. Значит ли это, что проблема в кодировщике? - person Coder; 02.05.2010
comment
Пока мы не можем ничего сделать (кодировщик может быть не проблемой, если он демонстрирует проблему как в JPEGEncoder, так и в ImageIO — имеет смысл, поскольку ImageIO, вероятно, использует JPEGEncoder внутри). Ваш следующий шаг — попытаться настроить BufferedImage. - person mdma; 02.05.2010
comment
настройка буферизованного изображения, как? - person Coder; 02.05.2010
comment
Этот метод приводит к ошибке с Java7: пакет com.sun.image.codec.jpeg не существует; хотя есть некоторые решения, этот класс может быть признан устаревшим в будущем и не является хорошим кандидатом для использования. - person Zon; 25.10.2013

Другой подход заключается в отображении изображения в формате TYPE_INT_ARGB, имеет DirectColorModel с альфа-каналом, как показано ниже и предложено здесь.

private BufferedImage process(BufferedImage old) {
    int w = old.getWidth();
    int h = old.getHeight();
    BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = img.createGraphics();
    g2d.drawImage(old, 0, 0, null);
    g2d.dispose();
    return img;
}
person trashgod    schedule 02.05.2010