Добавьте цветовой профиль изображения Tiff (sRGB или Adobe 1998) с помощью Java

Я искал в Интернете от и до, и я не могу найти решение о том, как добавить цветовой профиль sRGB или Abobe (1998) в изображение Tiff с помощью Java. Есть несколько примеров для jpg и png, но они не применимы к tiff. Я пытался сделать это с помощью Commons Imaging и java.awt, но мне не повезло. Является ли это возможным?

Спасибо

Обновлять:

Я добился некоторого прогресса, используя библиотеку изображений TwelveMonkeys imageio-tiff и следующий код:

File file = new File("/Users/user/Desktop/demo/sandal.tif");
BufferedImage image = ImageIO.read(file);

ICC_Profile ip = ICC_Profile.getInstance("/Users/user/Documents/icc/AdobeRGB1998.icc");
ICC_ColorSpace ics = new ICC_ColorSpace( ip );
ColorConvertOp cco = new ColorConvertOp( ics, null );
BufferedImage result = cco.filter(image, null);

ImageIO.write(result, "TIFF", new File("/Users/user/Desktop/demo/sandal2.tif"));

Цветовой профиль применяется, но tiff сглаживается, а альфа-канал удаляется. Как сохранить альфа-канал?


person jonD02    schedule 01.10.2016    source источник
comment
Возможный дубликат Как установить цветовой профиль icc в Java и изменение цветового пространства   -  person Erwin Bolwidt    schedule 01.10.2016
comment
Я пробовал это, и это не сработало. Либо потому, что он неполный, либо он не работает с Tiffs.   -  person jonD02    schedule 01.10.2016
comment
@ jonD02 В настоящее время TwelveMonkeys TIFFImageWriter будет записывать используемый профиль ICC, если только этот профиль не является профилем sRGB (как в ColorSpace.isCS_sRGB()). Это предполагает, что цветовое пространство TIFF по умолчанию — sRGB, что может быть неверным предположением. Но это должно работать для AdobeRGB1998. Можете ли вы связать файл sandal.tif из вашего примера кода? Если это так, я попытаюсь воспроизвести проблему и найти решение.   -  person Harald K    schedule 03.10.2016
comment
PS: только что попробовал ваш код (с некоторыми небольшими изменениями, поскольку у меня, очевидно, нет ваших файлов), и я получил хороший файл TIFF с сохраненной альфой и встроенным профилем ICC. Используя бот Java 1.8 в Windows и Java 1.7 в macOS, последние TwelveMonkeys собраны из master. Проверено в утилите ColorSync.   -  person Harald K    schedule 05.10.2016
comment
@haraldK Спасибо за ответ! Мне понравилась ваша библиотека. Я не знаю, как использовать TiffImageWriter, не могли бы вы предоставить демонстрацию? Вот ссылка на файл: drive.google.com/file/d /0B8FrShLAYpOEX25vU2NKM2xfNTA/   -  person jonD02    schedule 10.10.2016


Ответы (1)


Как упоминалось в комментариях, код, который у вас есть, должен был работать, если только в вашем ICC-профиле AdobeRGB1998 нет ничего особенного...

Приведенный ниже код работает для меня, преобразуя изображение из sRGB в профиль AdobeRGB1998. Полученный файл TIFF имеет правильный профиль ICC и содержит неповрежденный альфа-канал (258/BitsPerSample: [8, 8, 8, 8], 277/SamplesPerPixels: 4, 34675/ICCProfile: [...]). Единственные незначительные проблемы, которые я вижу, это то, что сжатие изменено с LZW на отсутствие сжатия, а DPI изменен с 300 на 72 (+ метаданные XMP потеряны).

BufferedImage image = ImageIO.read(new File("C:\\Downloads\\sandal.tif"));

ICC_ColorSpace ics = (ICC_ColorSpace) ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_1998);
ColorConvertOp cco = new ColorConvertOp(ics, null);
BufferedImage result = cco.filter(image, null);

File tempFile = File.createTempFile("test-", ".tif");
System.out.println("tempFile: " + tempFile); // Just to know where to look
ImageIO.write(result, "TIFF", tempFile);

Как видите, единственная реальная разница здесь заключается в том, как получается профиль/цветовое пространство ICC.

Если вы хотите сохранить метаданные и/или контролировать сжатие, это тоже возможно. Приведенный ниже код делает то же самое (но сохраняет сжатие LZW и разрешение 300 dpi), к сожалению, он немного более подробный:

try (ImageInputStream input = ImageIO.createImageInputStream(new File("C:\\Downloads\\sandal.tif"))) {
    ImageReader reader = ImageIO.getImageReaders(input).next();
    reader.setInput(input);
    IIOImage imageAndMeta = reader.readAll(0, reader.getDefaultReadParam());
    reader.dispose();

    ICC_ColorSpace ics = (ICC_ColorSpace) ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_1998);
    ColorConvertOp cco = new ColorConvertOp(ics, null);
    BufferedImage result = cco.filter((BufferedImage) imageAndMeta.getRenderedImage(), null);

    imageAndMeta.setRenderedImage(result);

    File tempFile = File.createTempFile("test-", ".tif");
    System.err.println("tempFile: " + tempFile);

    ImageWriter tiffWriter = ImageIO.getImageWritersByFormatName("TIFF").next();
    try (ImageOutputStream stream = ImageIO.createImageOutputStream(tempFile)) {
        tiffWriter.setOutput(stream);

        ImageWriteParam writeParam = tiffWriter.getDefaultWriteParam();

        // If you want a specific compression, uncommment these lines
        // The default setting is to copy from metadata
//        writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        // Allowed compression type values are: 
        // "None", "CCITT RLE", "CCITT T.4", "CCITT T.6","LZW", "JPEG", "ZLib", "PackBits" and "Deflate"
//        writeParam.setCompressionType("PackBits");

        tiffWriter.write(null, imageAndMeta, writeParam);
    }

    tiffWriter.dispose();
}

(по какой-то причине метаданные XMP все еще удаляются из вывода, я считаю, что это ошибка).

Тайлинг в настоящее время не поддерживается писателем, но в будущем он может управляться writeParam (используя для этого стандартный API). Ваше исходное изображение не мозаичное, поэтому я думаю, что это не так важно.

person Harald K    schedule 10.10.2016
comment
Спасибо! Это работает для цветового профиля, но создает проблему с другой частью моего приложения. Позже TIF используется для создания PNG с использованием следующего кода: - person jonD02; 21.10.2016
comment
'Файл файл = новый файл (tiffFile); Изображение BufferedImage = ImageIO.read (файл); BufferedImage resizeImagePng = resizeImage(изображение, BufferedImage.TYPE_INT_ARGB, image.getWidth()/4, image.getHeight()/4); ImageIO.write(resizeImagePng, PNG, новый файл(pngFile)); частный статический BufferedImage resizeImage (BufferedImage originalImage, тип int, int IMG_WIDTH, int IMG_HEIGHT) { BufferedImage resizedImage = new BufferedImage (IMG_WIDTH, IMG_HEIGHT, тип); Graphics2D g = resizedImage.createGraphics(); g.drawImage (исходное изображение, 0, 0, IMG_WIDTH, IMG_HEIGHT, ноль); г.распоряжаться(); вернуть измененное изображение; - person jonD02; 21.10.2016
comment
Полученный файл png с использованием tif с цветовым профилем: drive.google.com/open?id= 0B8FrShLAYpOEcDllb3BUYTNfTlE Этого не происходит, когда я обновляю Tif таким же образом в Photoshop: диск .google.com/open?id=0B8FrShLAYpOEUjNLQVBCVVJCQjA - person jonD02; 21.10.2016
comment
Я предлагаю вам задать новый вопрос для этого, так как комментарии предназначены только для уточнения текущего вопроса/ответа. :-) Постараюсь еще помочь! - person Harald K; 22.10.2016