I am using some file IO
and want to know if there is a method to check if a file is an image?
Other answers suggest to load full image into memory (ImageIO.read
) or to use standard JDK methods (MimetypesFileTypeMap
and Files.probeContentType
).
First way is not efficient if read image is not required and all you really want is to test if it is an image or not (and maybe to save it's content type to set it in Content-Type
response header when this image will be read in the future).
Inbound JDK ways usually just test file extension and not really give you result that you can trust.
The way that works for me is to use Apache Tika library.
private final Tika tika = new Tika();
private MimeType detectImageContentType(InputStream inputStream, String fileExtension) {
Assert.notNull(inputStream, "InputStream must not be null");
String fileName = fileExtension != null ? "image." + fileExtension : "image";
MimeType detectedContentType = MimeType.valueOf(tika.detect(inputStream, fileName));
log.trace("Detected image content type: {}", detectedContentType);
if (!validMimeTypes.contains(detectedContentType)) {
throw new InvalidImageContentTypeException(detectedContentType);
}
return detectedContentType;
}
The type detection is based on the content of the given document stream and the name of the document. Only a limited number of bytes are read from the stream.
I pass fileExtension
just as a hint for the Tika
. It works without it. But according to documentation it helps to detect better in some cases.
The main advantage of this method compared to ImageIO.read
is that Tika
doesn't read full file into memory - only first bytes.
The main advantage compared to JDK's MimetypesFileTypeMap
and Files.probeContentType
is that Tika
really reads first bytes of the file while JDK only checks file extension in current implementation.
If you plan to do something with read image (like resize/crop/rotate it), then use ImageIO.read
from Krystian's answer.
If you just want to check (and maybe store) real Content-Type
, then use Tika
(this answer).
If you work in the trusted environment and you are 100% sure that file extension is correct, then use Files.probeContentType
from prunge's Answer.
In Java 7, there is the java.nio.file.Files.probeContentType() method. On Windows, this uses the file extension and the registry (it does not probe the file content). You can then check the second part of the MIME type and check whether it is in the form <X>/image
.