某些图像文件类型是否始终与某些BufferedImage常量类型相对应?

时间:2014-01-11 02:49:26

标签: java image bufferedimage

Java中的BufferedImage类包含一个getType()方法,该方法返回一个与BufferedImage常量类型变量相关的整数,该变量描述了有关图像编码方式的一些信息(您可以查看BufferedImage source确定哪个数字对应于什么常量类型变量)。例如,如果它返回与BufferedImage.TYPE_3BYTE_BGR对应的整数,那么这意味着BufferedImage是一个8位RGB图像,没有alpha,蓝色,绿色和黄色各自用3位表示。

其中一些图像类型似乎与特定格式的某些属性相关联。例如,TYPE_BYTE_INDEXED表示它是从“256色6/6/6颜色立方体调色板”创建的。这听起来很像GIF图像,它是由256种颜色创建的。

好奇,我在硬盘上扫描了数百张照片,并使用ImageIO.read(File file)将每张照片转换为BufferedImage,然后在其上调用BufferedImage.getType()。我确定只有少数BufferedImage类型是从某些图像类型生成的。结果如下:

JPG: TYPE_3BYTE_BGR,TYPE_BYTE_GRAY

PNG: TYPE_3BYTE_BGR,TYPE_BYTE_GRAY,TYPE_4BYTE_BGRA

GIF: TYPE_BYTE_INDEXED

虽然看起来JPG和PNG共享了一些类似的BufferedImage常量类型,但我的测试中只有一个PNG导致TYPE_4BYTE_BGRA,而每个GIF都产生TYPE_BYTE_INDEXED

我对图像格式不太熟悉,而且我的样本量并不是那么大。所以我想我会问:假设图像格式正确,某些图像类型是否总是导致具有某些常量类型的BufferedImages?要提供具体示例,格式正确的GIF图像是否始终与TYPE_BYTE_INDEXED对应?或者所有格式正确的图像是否可以与所有BufferedImage常量类型相对应?

1 个答案:

答案 0 :(得分:7)

  

[Do]某些图像类型总是导致BufferedImage具有某些常量类型?

in your other question一样; 不,BufferedImage类型和文件格式之间没有直接关系。

  

或者所有格式正确的图像是否可以与所有BufferedImage常量类型对应?

基本上,是的。当然,如果转换为灰色,彩色图像会丢失信息, 如果每个样本转换为8位等,每个样本16位图像将失去精度


但是,不同的文件格式有不同的存储像素和颜色的方式,通常某种BufferedImage类型更接近地表示文件格式中使用的“布局”。

让我们使用您的GIF示例:

GIF的存储“布局”(在应用LZW压缩之前)通常最接近TYPE_BYTE_INDEXED的存储“布局”,因此这通常是用Java做的“最便宜”的转换。对于最多16种颜色的GIF,TYPE_BYTE_BINARY也可以正常工作。如果没有透明色,则GIF始终可以解码为TYPE_4BYTE_ABGRTYPE_INT_ARGB(甚至TYPE_3BYTE_BGRTYPE_INT_RGB

换句话说,图像的类型取决于解码器,在某些情况下(例如the ImageIO API)用户。

总结一下,您发现的是,默认情况下,ImageIO的GIF插件(GIFImageReader)会将超过16种颜色的GIF解码为TYPE_BYTE_INDEXED。使用不同的解码器/框架可能会产生不同的结果。


一些可能启发好奇读者的历史:

未建模以对应图像格式的BufferedImage的类型。它们被建模为对应于显示硬件。具有与显示硬件相同的像素布局的图像总是更快地显示。其他布局首先需要经过某种转换。现在,现代显示硬件非常快,这当然不是一个问题,但在“古代”时代,这很重要。

顺便提一下,许多“古老”图像格式是临时创建的,或者是在特定显示硬件上运行的特定应用程序。因此,显示硬件的像素布局通常以文件格式使用。同样,因为不需要转换,这是最快/最简单的实现。

所以,是的,有一种关系。这不是直接的“给定A => B”关系,而是“给定A C => B”。