java 测试文件是否为图像文件

lf3rwulv  于 2023-11-15  发布在  Java
关注(0)|答案(8)|浏览(118)

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

flseospp

flseospp1#

这对我来说很好。希望我能帮上忙

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");
    }
}

字符串

j2cgzkjk

j2cgzkjk2#

if( ImageIO.read(*here your input stream*) == null)
    *IS NOT IMAGE*

字符串
答案:How to check a uploaded file whether it is a image or other file?

w8biq8rn

w8biq8rn3#

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

iih3973s

iih3973s4#

你可以尝试这样的东西:

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");
}

字符串

3duebb1j

3duebb1j5#

其他答案建议将完整图像加载到内存中(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;
}

字符串
类型检测是基于给定文档流的内容和文档的名称。仅从流中读取有限数量的字节。
我传递fileExtension只是作为Tika的一个 * 提示 *。它没有它也能工作。但根据文档,它有助于在某些情况下更好地检测。

  • ImageIO.read相比,这种方法的主要优点是Tika不会将整个文件读入内存-只读取第一个字节。
  • 与JDK的MimetypesFileTypeMapFiles.probeContentType相比,Tika的主要优点是Tika真正读取文件的第一个字节,而JDK在当前实现中只检查文件扩展名。

TLDR

  • 如果你打算对读取的图像做一些事情(比如调整大小/裁剪/旋转),那么使用ImageIO.read from Krystian's answer
  • 如果你只是想检查(或者存储)真实的Content-Type,那么使用Tika(这个答案)。
  • 如果您在受信任的环境中工作,并且您100%确定文件扩展名是正确的,则从prunge's Answer使用Files.probeContentType
e0uiprwp

e0uiprwp6#

你可以尝试这样的东西:

import javax.activation.MimetypesFileTypeMap;

   File myFile;

   String mimeType = new MimetypesFileTypeMap().getContentType( myFile ));
   // mimeType should now be something like "image/png"

   if(mimeType.substring(0,5).equalsIgnoreCase("image")){
         // its an image
   }

字符串
这应该可以工作,尽管它似乎不是最优雅的版本。

dm7nw8vv

dm7nw8vv7#

有很多方法可以做到这一点;请参阅其他答案和相关问题的链接(Java 7方法对我来说似乎最有吸引力,因为它默认使用特定于平台的约定,并且您可以提供自己的文件类型确定方案。

然而,我只想指出没有任何机制是绝对正确的

  • 如果后缀不标准或错误,依赖文件后缀的方法将被欺骗。
  • 依赖于文件属性的方法(例如,在文件系统中)将被欺骗,如果文件有一个不正确的内容类型属性或根本没有。
  • 依赖于查看文件签名的方法可能会被恰好具有相同签名字节的二进制文件欺骗。
  • 如果你运气不好,即使只是尝试将文件作为图像读取也会被欺骗.这取决于你尝试的图像格式。
63lcw9qa

63lcw9qa8#

下面是我的代码,基于使用tika的答案。

private static final Tika TIKA = new Tika();
public boolean isImageMimeType(File src) {
    try (FileInputStream fis = new FileInputStream(src)) {
        String mime = TIKA.detect(fis, src.getName());
        return mime.contains("/") 
                && mime.split("/")[0].equalsIgnoreCase("image");
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

字符串

相关问题