2016-08-24 29 views
0

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

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做一些特定的事吗?感谢您的任何帮助,您可以提供。

+0

从迄今为止我所做的研究看来,他们似乎做到了。我也有透明TIF的例子 – Justin

+0

嗯..为什么你将源头拖到目的地两次(并沿途创建两个'Graphics'上下文)? – haraldK

回答

0

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

如果你需要一个透明的TIFF,你的选择是:

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