使用 Java 添加 Tiff 图像颜色配置文件(sRGB 或 Adobe 1998)
Add Tiff Image Color Profile (sRGB or Adobe 1998) with Java
我在网上到处搜索,但找不到如何将 sRGB 或 Abobe (1998) 颜色配置文件添加到带有 Java 的 Tiff 图像的解决方案。有一些关于 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 被展平并删除了 alpha。如何保留 Alpha 通道?
如评论中所述,您的代码应该有效,除非您的 AdobeRGB1998 ICC 配置文件有一些特别之处...
下面的代码对我有用,将图像从 sRGB 转换为 AdobeRGB1998 配置文件。生成的 TIFF 文件具有正确的 ICC 配置文件并包含完整的 alpha 通道 (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 profile/color space。
如果你想保留元数据and/or控制压缩,那也是可以的。下面的代码基本相同(但保留了 LZW 压缩和 300dpi),不幸的是它有点冗长:
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 来实现)。您的原始图片没有平铺,所以我想这不是什么大问题。
我在网上到处搜索,但找不到如何将 sRGB 或 Abobe (1998) 颜色配置文件添加到带有 Java 的 Tiff 图像的解决方案。有一些关于 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 被展平并删除了 alpha。如何保留 Alpha 通道?
如评论中所述,您的代码应该有效,除非您的 AdobeRGB1998 ICC 配置文件有一些特别之处...
下面的代码对我有用,将图像从 sRGB 转换为 AdobeRGB1998 配置文件。生成的 TIFF 文件具有正确的 ICC 配置文件并包含完整的 alpha 通道 (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 profile/color space。
如果你想保留元数据and/or控制压缩,那也是可以的。下面的代码基本相同(但保留了 LZW 压缩和 300dpi),不幸的是它有点冗长:
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 来实现)。您的原始图片没有平铺,所以我想这不是什么大问题。