我正在使用xuggler在视频中放置透明蒙版。
我试图使用ImageIO.read()打开一个有效的png,但是当它呈现时,我的图片中总是有一个白色的背景。
这是我的阅读代码。
url = new URL(stringUrl);
imagem = ImageIO.read(url);
boolean hasAlpha = imagem.getColorModel().hasAlpha();
此布尔值始终为false。
当我制作渲染时,在Xuggler中
mediaReader .setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
我做错了什么?
答案 0 :(得分:1)
"问题"与原始图像文件一样,它是一个24位RGB(3通道)PNG,带有templateURL
块。
tRNS
chunk指定要用完全透明的像素替换的颜色(在这种情况下为tRNS
或白色)。实际上,应用此透明度有点像位掩码,其中所有像素都是完全透明或完全不透明。但是,作为"ancillary" (optional, or non-critical) chunk according to the PNG specificiation,PNG解码器可能会选择忽略此信息。
不幸的是,ImageIO的默认255, 255, 255
(" PNG插件")似乎不应用此位掩码,而是将图像保持为完全不透明的RGB(这仍然是规范合规行为)。
您的第二个图像文件是32位RGBA(4个通道,包括alpha)。在这种情况下,任何读者必须(并且确实)解码所有通道,包括完整的8位alpha通道。 ImageIO的PNGImageReader
确实以预期的透明度对其进行解码。
PS:可能是"修复"第一张图片的透明度,使用meta data。
图片的元数据包含native PNG format中的以下信息:
PNGImageReader
解析完之后,你可以转换图像,首先创建一个新的4通道图像(如<javax_imageio_png_1.0>
....
<tRNS>
<tRNS_RGB red="255" green="255" blue="255"/>
</tRNS>
</javax_imageio_png_1.0>
),将R,G和B通道复制到这个新图像,最后将alpha通道设置为TYPE_4BYTE_ABGR
为(与透明色匹配的所有像素)或0
(对于所有其他像素)。
PPS:您可能希望直接在255
上执行这些操作,因为使用Raster
方法会将值转换为BufferedImage.getRGB(..)/setRGB(..)
颜色配置文件,这可能不完全匹配来自sRGB
块的RGB值。