Розовый / красноватый оттенок при изменении размера изображений JPEG с помощью java thumbnailator или imgscalr
Я пытаюсь преобразовать изображение (URL ниже), используя две библиотеки (thumbnailator и imgscalr. Мой код работает с большинством изображений, за исключением нескольких, которые после преобразования имеют розовый / красноватый оттенок.
Я пытаюсь понять причину и приветствую любую рекомендацию.
Примечание. Тип изображения для этого изображения - 5, т.е. BufferedImage.TYPE_3BYTE_BGR, и я использую Java 7.
Использование Thumbnailator
Thumbnails.of(fromDir.listFiles())
.size(thumbnailWidth, thumbnailHeight)
.toFiles(Rename.SUFFIX_HYPHEN_THUMBNAIL);
Использование imgscalr
BufferedImage bufferedImage = ImageIO.read(file);
final BufferedImage jpgImage;
LOG.debug("image type is =[{}] ", bufferedImage.getType());
BufferedImage scaledImg = Scalr.resize(bufferedImage, Method.ULTRA_QUALITY, thumbnailWidth, thumbnailHeight, Scalr.OP_ANTIALIAS);
File thumbnailFile = new File(fromDirPath + "/" + getFileName(file.getName()) +THUMBNAIL_KEYWORD + ".png");
ImageIO.write(scaledImg, getFileExtension(file.getName()), thumbnailFile);
bufferedImage.flush();
scaledImg.flush();
2 ответа
Я часто получаю этот вопрос (автор imgscalr) - проблема почти всегда заключается в том, что вы читаете / записываете файлы разных форматов, а канал ALPHA приводит к тому, что один из ваших цветовых каналов (R/G/B) отбирается из результирующий файл.
Например, если вы прочитали в файле, который был ARGB (4 канала), и записали его в формате JPG (3 канала) - если только вы не намеренно манипулируете типами изображений самостоятельно и не визуализируете старое изображение непосредственно в новом, вы получите файл с каналами "ARG"... или, точнее, только красный и зеленый - без синего.
PNG поддерживает альфа-канал, а JPG - нет, так что имейте это в виду.
Чтобы это исправить, нужно целенаправленно создавать соответствующие BufferedImage правильного типа (RGB, ARGB и т. Д.) И использовать destImage.getGraphics()
вызов, чтобы отрендерить одно изображение другому, прежде чем записать его на диск и перекодировать.
Sun и Oracle НИКОГДА не делали библиотеки ImageIO достаточно умными, чтобы обнаруживать неподдерживаемые каналы при записи в файлы разных типов, поэтому такое поведение происходит постоянно:(
Надеюсь, это поможет!
Следующий фрагмент кода решил мою проблему:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Thumbnails.of(new ByteArrayInputStream(imageByteArray))
.outputFormat("jpg")
.size(200, 200)
.toOutputStream(outputStream);
return baos.toByteArray();
Я использую Thumbnailator и код был размещен здесь: https://github.com/coobird/thumbnailator/issues/23