3

I'm learning to program in Java and right now I'm trying to make a program with GUI in Swing, which would make a slideshow out of images in a given directory. Now, my question is can you check whether a file is really an image?

I'm talking about a file that not only has the correct extension, like e.g. .jpg or .png, but also contains content that is.. interpretable as an image I guess? My wording here might not be precise.

I know I'm asking for quite a bit, but I'd be very grateful if someone could answer that. (Not a duplicate of Test if a file is an image file, because I think that the author there meant the extensions themselves).

halfer
  • 19,824
  • 17
  • 99
  • 186
nfsu
  • 113
  • 2
  • 10
  • Ive never done something like this but im guessing you could have conditional logic that attempts to decode JPEGs or PNGs? Maybe something like this https://www.java-tips.org/java-se-tips-100019/23-java-awt-image/2283-png-file-format-decoder-in-java.html – dave May 15 '18 at 21:28
  • 1
    Of course. You can use one of the several Java APIs you were going to use anyway to attempt to load the file as an image. If it is not of correct form, then you will get an exception (that you can handle appropriately) or some other error indicator. How else *could* one do it? – John Bollinger May 15 '18 at 21:44
  • @aquaballin will try it out, ty. Still looking for additional answers though :) – nfsu May 15 '18 at 21:44
  • Possible duplicate of [Test if a file is an image file](https://stackoverflow.com/questions/9643228/test-if-a-file-is-an-image-file) – user641887 May 15 '18 at 21:46
  • @JohnBollinger so for example if I try to construct image icon object with non-image File as an argument in constructor it should already throw an exception, is that right? – nfsu May 15 '18 at 21:46
  • @nfsu Why don't you try it and see for yourself if exception is thrown? – Andreas May 15 '18 at 21:47
  • 1
    @nfsu, in the particular case of the `ImageIcon` constructor you're talking about, the image is loaded asynchronously, so the constructor will not throw. In that case, you need to rely instead on the "some other error indicator", which for `ImageIcon` would come from the `getImageLoadStatus​()` method. – John Bollinger May 15 '18 at 21:53
  • 1
    Use `ImageIO.read`, it will throw an `IOException` if the `File` is not a valid (or supported) image format – MadProgrammer May 15 '18 at 22:07

2 Answers2

5

Most image files start with a magic number, so for a quick check, look for that.

E.g. a PNG file always start with bytes 89 50 4E 47 0D 0A 1A 0A.

I'll leave the research for magic numbers of whatever image formats you want to support up to you.

UPDATE: See also list of file signatures on Wikipedia (courtesy of DevilsHnd).

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • That's extremely interesting, didn't know that. Thanks for sharing the knowledge. I guess that this combined with what @JohnBollinger said sums it all up for me. Thanks guys – nfsu May 15 '18 at 22:00
  • 1
    Just as additional reference: [File Signatures](https://en.wikipedia.org/wiki/List_of_file_signatures). – DevilsHnd - 退職した May 16 '18 at 04:15
  • This is the best and accurate way to determine whether the given file is actually an image file. Alternatively you can also use URLConnection.guessContentTypeFromStream(InputStream) which does the check by looking at the bytes. Below is part of the Javadoc taken from this method: Direct inspection of the bytes to determine the content type is often more accurate than believing the content type claimed by the server. – Sharadr Dec 17 '19 at 04:37
4

I would just try loading it as an image and seeing if you get an image:

import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Main
{
    public static void main(String[] args) throws IOException
    {
        System.out.println(isImage(new File("./dataset1.csv")));  // false
        System.out.println(isImage(new File("./graph.png")));  // true
    }

    public static boolean isImage(File file)
    {
        try {
            return ImageIO.read(file) != null;
        } catch (Exception e) {
            return false;
        }
    }
}
Daniel Centore
  • 3,220
  • 1
  • 18
  • 39