【问题标题】:How to make a TIFF transparent in Java using JAI?如何使用 JAI 在 Java 中使 TIFF 透明?
【发布时间】:2016-08-24 03:11:47
【问题描述】:

我正在尝试使用 Java 高级成像 (JAI) 从 BufferedImage 编写 TIFF,但不确定如何使其透明。以下方法可用于使 PNG 和 GIF 透明:

private static BufferedImage makeTransparent(BufferedImage image, int x, int y) {
    ColorModel cm = image.getColorModel();
    if (!(cm instanceof IndexColorModel)) {
        return image;
    }
    IndexColorModel icm = (IndexColorModel) cm;
    WritableRaster raster = image.getRaster();
    int pixel = raster.getSample(x, y, 0);
    // pixel is offset in ICM's palette
    int size = icm.getMapSize();
    byte[] reds = new byte[size];
    byte[] greens = new byte[size];
    byte[] blues = new byte[size];
    icm.getReds(reds);
    icm.getGreens(greens);
    icm.getBlues(blues);
    IndexColorModel icm2 = new IndexColorModel(8, size, reds, greens, blues, pixel);
    return new BufferedImage(icm2, raster, image.isAlphaPremultiplied(), null);
}

但是在编写 TIFF 时,背景总是白色的。以下是我用于编写 TIFF 的代码:

BufferedImage destination = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_BYTE_INDEXED);
Graphics imageGraphics = destination.getGraphics();
imageGraphics.drawImage(sourceImage, 0, 0, backgroundColor, null);
if (isTransparent) {
    destination = makeTransparent(destination, 0, 0);
}
destination.createGraphics().drawImage(sourceImage, 0, 0, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
TIFFImageWriter writer = new TIFFImageWriter(new TIFFImageWriterSpi());
writer.setOutput(ios);
writer.write(destination);

我稍后也会进行一些元数据操作,因为我实际上是在处理 GeoTIFF。但此时图像仍然是白色的。调试时,我可以查看BufferedImage,它是透明的,但是当我写图像时,文件有白色背景。我需要对 TiffImageWriteParam 做一些特定的事情吗?感谢您提供的任何帮助。

【问题讨论】:

  • 从我目前所做的研究来看,他们似乎确实如此。我也有透明 tif 的例子
  • Hmmm.. 为什么要将源绘制到目标两次(并在此过程中创建两个 Graphics 上下文)?

标签: java image transparent tiff jai


【解决方案1】:

TIFF 没有在调色板中存储透明度信息(Alpha 通道)的选项(如在您的IndexedColorModel 中)。调色板仅支持 RGB 三元组。因此,当您将图像写入 TIFF 时,将颜色索引设置为透明的事实就会丢失。

如果您需要透明的 TIFF,您的选择是:

  • 使用普通 RGBA 代替索引颜色(RGB,4 个样本/像素,不关联的 alpha)。可能只使用BufferedImage.TYPE_INT_ARGBTYPE_4BYTE_ABGR。这将使输出文件更大,但易于实现,并且应该更兼容。几乎所有 TIFF 软件都支持。
  • 使用调色板图像保存单独的透明度蒙版(光度解释设置为 4 的 1 位图像)。不确定它是否被很多软件支持,有些可能会将遮罩显示为单独的黑白图像。不确定如何在 JAI/ImageIO 中实现这一点,可能需要编写一个序列并设置一些额外的元数据。
  • 存储包含透明索引的自定义字段。除您自己的软件外,其他任何软件均不支持该文件,但该文件仍将兼容并在其他软件中以白色(纯色)背景显示。您应该可以使用 TIFF 元数据进行设置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多