Добавить цветовой профиль Tiff Image (sRGB или Adobe 1998) с помощью Java
Я искал в Интернете все выше и ниже, и не могу найти решение, как добавить цветовой профиль sRGB или Abobe (1998) в Tiff Image с Java. Есть несколько примеров для jpgs и pngs, но они не относятся к tiff. Я пытался сделать это с помощью Commons Imaging и java.awt, но безуспешно. Является ли это возможным?
Спасибо
Обновить:
Я добился определенного прогресса, используя библиотеку TwioMonkeys 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 сглаживается и альфа удаляется. Как сохранить альфа-канал?
1 ответ
Как уже упоминалось в комментариях, ваш код должен был сработать, если в вашем профиле AdobeRGB1998 ICC нет ничего особенного...
Приведенный ниже код работает для меня, конвертируя изображение из 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 точек на дюйм), к сожалению, он немного более подробный:
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). Ваше оригинальное изображение не выложено плиткой, поэтому я думаю, что это не так важно.