Can I tell what the file type of a BufferedImage originally was?

Thunderforge picture Thunderforge · Jan 11, 2014 · Viewed 17.5k times · Source

In my code, I have a BufferedImage that was loaded with the ImageIO class like so:

BufferedImage image = ImageIO.read(new File (filePath);

Later on, I want to save it to a byte array, but the ImageIO.write method requires me to pick either a GIF, PNG, or JPG format to write my image as (as described in the tutorial here).

I want to pick the same file type as the original image. If the image was originally a GIF, I don't want the extra overhead of saving it as a PNG. But if the image was originally a PNG, I don't want to lose translucency and such by saving it as a JPG or GIF. Is there a way that I can determine from the BufferedImage what the original file format was?

I'm aware that I could simply parse the file path when I load the image to find the extension and just save it for later, but I'd ideally like a way to do it straight from the BufferedImage.

Answer

haraldK picture haraldK · Jan 12, 2014

As @JarrodRoberson says, the BufferedImage has no "format" (i.e. no file format, it does have one of several pixel formats, or pixel "layouts"). I don't know Apache Tika, but I guess his solution would also work.

However, if you prefer using only ImageIO and not adding new dependencies to your project, you could write something like:

ImageInputStream input = ImageIO.createImageInputStream(new File(filePath));

try {
    Iterator<ImageReader> readers = ImageIO.getImageReaders(input);

    if (readers.hasNext()) {
        ImageReader reader = readers.next();

        try {
            reader.setInput(input);

            BufferedImage image = reader.read(0);  // Read the same image as ImageIO.read

            // Do stuff with image...

            // When done, either (1):
            String format = reader.getFormatName(); // Get the format name for use later
            if (!ImageIO.write(image, format, outputFileOrStream)) {
                // ...handle not written
            }
            // (case 1 done)

            // ...or (2):
            ImageWriter writer = ImageIO.getImageWriter(reader); // Get best suitable writer

            try {
                ImageOutputStream output = ImageIO.createImageOutputStream(outputFileOrStream);

                try {
                    writer.setOutput(output);
                    writer.write(image);
                }
                finally {
                    output.close();
                }
            }
            finally {
                writer.dispose();
            }
            // (case 2 done)
        }
        finally {
            reader.dispose();
        }
    }
}
finally {
    input.close();
}