Test if a file is an image file

后端 未结 8 1236
情深已故
情深已故 2020-12-01 07:55

I am using some file IO and want to know if there is a method to check if a file is an image?

相关标签:
8条回答
  • 2020-12-01 08:24

    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.

    TLDR

    • 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.

    0 讨论(0)
  • 2020-12-01 08:26

    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.

    0 讨论(0)
提交回复
热议问题