The BufferedImage class in Java contains a getType()
method which returns an integer correlating with a BufferedImage constant type variable describing some information about how the image is encoded (you can look at the BufferedImage source to determine what number corresponds to what constant type variable). For instance, if it returns the integer corresponding with BufferedImage.TYPE_3BYTE_BGR
, then that means that the BufferedImage is an 8-bit RGB image with no alpha and with blue, green, and yellow each being represented by 3 bits.
Some of these image types seem to correlate with certain properties of a particular format. For instance, TYPE_BYTE_INDEXED
says that it is created from "a 256-color 6/6/6 color cube palette". This sounds a lot like GIF images, which are created from 256 colors.
Curious, I scanned several hundred photos on my hard drive and converted each of them to a BufferedImage, using ImageIO.read(File file)
, then called BufferedImage.getType()
on them. I determined that there were only a few BufferedImage types that were generated from certain image types. The results were as follows:
JPG: TYPE_3BYTE_BGR, TYPE_BYTE_GRAY
PNG: TYPE_3BYTE_BGR, TYPE_BYTE_GRAY, TYPE_4BYTE_BGRA
GIF: TYPE_BYTE_INDEXED
While it looks like both JPGs and PNGs shared some similar BufferedImage constant types, only a PNG in my test resulted in a TYPE_4BYTE_BGRA
and every GIF resulted in a TYPE_BYTE_INDEXED
.
I'm not too familiar with image formats and it's true that my sample size isn't all that large. So I figured I'd ask: assuming that an image is properly formatted, do certain image types always result in BufferedImages with certain constant types? To provide a specific example, would a properly formatted GIF image always correspond to TYPE_BYTE_INDEXED
? Or is it possible for all properly formatted images to correspond with all of the BufferedImage constant types?
[Do] certain image types always result in
BufferedImage
with certain constant types?
As in in your other question; No, there is no direct relationship between the BufferedImage
types and file formats.
Or is it possible for all properly formatted images to correspond with all of the
BufferedImage
constant types?
Basically, yes. Of course, a color image would lose information if converted to gray, a 16 bit per sample image would lose precision if converted to 8 bits per sample, etc.
However, different file formats have different ways of storing pixels and colors, and usually a certain BufferedImage
type more closely represent the "layout" used in the file format.
Let's use your GIF example:
The storage "layout" of a GIF (before applying LZW compression) is normally closest to that of TYPE_BYTE_INDEXED
, so that is usually the "cheapest" conversion to do in Java. For GIFs with up to 16 colors, TYPE_BYTE_BINARY
would work just as well. And it's always possible for a GIF to be decoded into TYPE_4BYTE_ABGR
or TYPE_INT_ARGB
(or even TYPE_3BYTE_BGR
or TYPE_INT_RGB
if no transparent color).
In other words, the type of image depends on the decoder, and in some cases (like for the ImageIO
API) the user.
To summarize, what you have found, is that the GIF plugin for ImageIO (GIFImageReader
) by default will decode a GIF with more than 16 colors to TYPE_BYTE_INDEXED
. Using a different decoder/framework may yield different results.
A little bit of history that might enlighten the curious reader:
The types of BufferedImage
s where not modeled to correspond to image formats. They were modeled to correspond to display hardware. An image having the same pixel layout as the display hardware is always going to be faster to display. Other layouts would first need to go through some kind of conversion. Now with modern display hardware being very fast, this is of course less of a concern, but in "ancient" times this was important.
Incidentally, many "ancient" image formats were created ad hoc, or for specific applications running on specific display hardware. Because of this, the pixel layout of the display hardware were often used in the file format. Again, because no conversion was needed, and it was the fastest/simplest thing to implement.
So, yes, there is a relationship. It's just not a direct "given A => B" relationship, it's a "given A and C => B".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With