测试文件是否为图像文件

lan*_*day 32 java io image file

我正在使用一些文件IO,想知道是否有方法来检查文件是否是图像?

Ism*_*reu 48

这对我很有用.希望我能提供帮助

import javax.activation.MimetypesFileTypeMap;
import java.io.File;
class Untitled {
    public static void main(String[] args) {
        String filepath = "/the/file/path/image.jpg";
        File f = new File(filepath);
        String mimetype= new MimetypesFileTypeMap().getContentType(f);
        String type = mimetype.split("/")[0];
        if(type.equals("image"))
            System.out.println("It's an image");
        else 
            System.out.println("It's NOT an image");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我试过但它总是返回"application/octet-stream (5认同)
  • 这是测试文件是否为图像的不良方法.更好的解决方案是:Files.probeContentType(path); (5认同)
  • 这仅根据文件的扩展名进行检查.使用此方法无法检测到无效图像(没有图像内容和正确文件头的其他二进制文件). (4认同)

Kry*_*ian 23

if( ImageIO.read(*here your input stream*) == null)
    *IS NOT IMAGE*    
Run Code Online (Sandbox Code Playgroud)

还有一个答案:如何检查上传的文件,无论是图像还是其他文件?


pru*_*nge 12

在Java 7中,有java.nio.file.Files.probeContentType()方法.在Windows上,它使用文件扩展名和注册表(它不会探测文件内容).然后,您可以检查MIME类型的第二部分,并检查它是否在表单中<X>/image.

  • 在 Linux 上,它似乎只查看我机器上的扩展。将 .jpeg 文件更改为 .txt 并返回“text/plain”。我喜欢下面克里斯蒂安的回答。 (3认同)
  • 它工作但你应该使用第一部分"image/jpeg" (2认同)

Bia*_*aro 9

你可以尝试这样的事情:

String pathname="abc\xyz.png"
File file=new File(pathname);


String mimetype = Files.probeContentType(file.toPath());
//mimetype should be something like "image/png"

if (mimetype != null && mimetype.split("/")[0].equals("image")) {
    System.out.println("it is an image");
}
Run Code Online (Sandbox Code Playgroud)


Rus*_*nko 5

其他答案建议将完整图像加载到内存中 ( ImageIO.read) 或使用标准 JDK 方法 (MimetypesFileTypeMapFiles.probeContentType)。

如果不需要读取图像,并且您真正想要的只是测试它是否是图像(并且可能保存其内容类型以Content-Type在将来读取该图像时将其设置在响应标头中),则第一种方法效率不高。

入站 JDK 方法通常只是测试文件扩展名,并不能真正给出您可以信任的结果。

对我有用的方法是使用Apache Tika库。

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;
}
Run Code Online (Sandbox Code Playgroud)

类型检测基于给定文档流的内容和文档的名称。仅从流中读取有限数量的字节。

我通过fileExtension只是作为一个提示Tika。没有它它也能工作。但根据文档,在某些情况下它有助于更​​好地检测。

  • 与此方法相比,此方法的主要优点ImageIO.readTika不会将整个文件读入内存 - 仅读取第一个字节。

  • MimetypesFileTypeMap与 JDK 相比,主要优点Files.probeContentTypeTika真正读取文件的第一个字节,而 JDK 在当前实现中仅检查文件扩展名。

总长DR

  • 如果您打算对读取的图像执行某些操作(例如调整大小/裁剪/旋转它),请使用ImageIO.readKrystian的答案

  • 如果您只想检查(也许存储) real Content-Type,则使用Tika(此答案)。

  • 如果您在受信任的环境中工作并且 100% 确定文件扩展名正确,则使用Files.probeContentTypeprunge的 Answer