Розовый / красноватый оттенок при изменении размера изображений 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

Другие вопросы по тегам