使用Java添加Tiff图像颜色配置文件(sRGB或Adobe 1998)

时间:2016-10-01 02:54:24

标签: java color-profile twelvemonkeys

我搜索了网络的高低,我找不到如何将sRGB或Abobe(1998)颜色配置文件添加到带有Java的Tiff图像的解决方案。有一些关于jpgs和pngs的例子,但它们不适用于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通道?

1 个答案:

答案 0 :(得分:0)

正如评论中所提到的,您所拥有的代码应该有效,除非您的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配置文件/颜色空间。

如果您想保留元数据和/或控制压缩,那也是可能的。下面的代码基本相同(但保留了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来实现)。你的原始图像没有平铺,所以我想这不是一个问题。