java 检查文件是否为图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2192717/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 19:58:01  来源:igfitidea点击:

Check if a file is an image

javaimagejai

提问by Tim

I am using JAI and create a file with:

我正在使用 JAI 并创建一个文件:

PlanarImage img = JAI.create("fileload", myFilename);

I check before that line if the file exists. But how could I check if the file is a .bmp or a .tiff or an image file?

我在该行之前检查文件是否存在。但是我如何检查文件是 .bmp 还是 .tiff 或图像文件?

Does anyone know?

有人知道吗?

采纳答案by SyntaxT3rr0r

The Image Magick project has facilities to identify image and there's a Java wrapper for Image Magick called JMagick which I think you may want to consider instead of reinventing the wheel:

Image Magick 项目具有识别图像的功能,并且有一个名为 JMagick 的 Image Magick 的 Java 包装器,我认为您可能需要考虑而不是重新发明轮子:

http://www.jmagick.org

http://www.jmagick.org

I'm using Image Magick all the time, including its "identify" feature from the command line and it never failed once to identify a picture.

我一直在使用 Image Magick,包括它在命令行中的“识别”功能,而且它从未失败过一次识别图片。

Back in the days where I absolutely needed that feature and JMagick didn't exist yet I used to Runtime.exec()ImageMagick's identifycommand from Java and it worked perfectly.

回到我绝对需要该功能而 JMagick 尚不存在的时代,我已经习惯了Java 中的Runtime.exec()ImageMagickidentify命令并且它运行良好。

Nowadays that JMagick exist this is probably not necessary anymore (but I haven't tried JMagick yet).

现在 JMagick 存在,这可能不再需要(但我还没有尝试过 JMagick)。

Note that it gives much more than just the format, for example:

请注意,它提供的不仅仅是格式,例如:

$  identify tmp3.jpg 
tmp3.jpg JPEG 1680x1050 1680x1050+0+0 DirectClass 8-bit 293.582kb 

$  identify tmp.png
tmp.png PNG 1012x900 1012x900+0+0 DirectClass 8-bit 475.119kb

回答by Estuardo López

Try using the width of the image:

尝试使用图像的宽度:

boolean isImage(String image_path){
  Image image = new ImageIcon(image_path).getImage();
  if(image.getWidth(null) == -1){
        return false;
  }
  else{
        return true;
  }
}

if the width is -1 then is not image.

如果宽度为 -1,则不是图像。

回答by Matt Wear

To tell if something is a png, I've used this below snippet in Android java.

为了判断某个东西是否是 png,我在 Android java 中使用了以下代码段。

public CompressFormat getCompressFormat(Context context, Uri fileUri) throws IOException {
    // create input stream
    int numRead;
    byte[] signature = new byte[8];
    byte[] pngIdBytes = { -119, 80, 78, 71, 13, 10, 26, 10 };
    InputStream is = null;

    try {
        ContentResolver resolver = context.getContentResolver();
        is = resolver.openInputStream(fileUri);

        // if first 8 bytes are PNG then return PNG reader
        numRead = is.read(signature);

        if (numRead == -1)
            throw new IOException("Trying to reda from 0 byte stream");

    } finally {
        if (is != null)
            is.close();
    }

    if (numRead == 8 && Arrays.equals(signature, pngIdBytes)) {
        return CompressFormat.PNG;
    }

    return null;
}

回答by Fabian Steeg

You could use DROID, a tool for file format identification that also offers a Java API, to be used roughly like this:

您可以使用DROID,一种用于文件格式识别的工具,它也提供了一个 Java API,大致如下使用:

AnalysisController controller = new AnalysisController();
controller.readSigFile(signatureFileLocation);
controller.addFile(fileToIdentify.getAbsolutePath());
controller.runFileFormatAnalysis();
Iterator<IdentificationFile> it = controller.getFileCollection().getIterator();

Documentation on the API usage is rather sparse, but you can have a look at this working example(the interesting part is in the identifyOneBinarymethod).

关于 API 使用的文档相当稀少,但您可以查看这个工作示例(有趣的部分在identifyOneBinary方法中)。

回答by Birkan Cilingir

At the beginning of files, there is an identifying character sequence. For example JPEG files starts with FF D8 FF.

在文件的开头,有一个识别字符序列。例如,JPEG 文件以 FF D8 FF 开头。

You can check for this sequence in your program but I am not sure whether this works for every file.

您可以在程序中检查此序列,但我不确定这是否适用于每个文件。

For information about identifying characters you can have a look at http://filext.com

有关识别字符的信息,您可以查看http://filex.com

回答by David Harris

The only (semi-)reliable way to determine the contents of a file is to open it and read the first few characters. Then you can use a set of tests such as implemented in the Unix file command to make an educated guess as to the contents of the file.

确定文件内容的唯一(半)可靠方法是打开它并读取前几个字符。然后,您可以使用一组测试(例如在 Unix file 命令中实现的测试)来对文件的内容进行有根据的猜测。

回答by Akin Okegbile

if(currentImageType ==null){
                    ByteArrayInputStream is = new ByteArrayInputStream(image);
                    String mimeType = URLConnection.guessContentTypeFromStream(is);
                    if(mimeType == null){
                        AutoDetectParser parser = new AutoDetectParser();
                        Detector detector = parser.getDetector();
                        Metadata md = new Metadata();
                        mimeType = detector.detect(is,md).toString();

                        if (mimeType.contains("pdf")){
                            mimeType ="pdf";
                        }
                        else if(mimeType.contains("tif")||mimeType.contains("tiff")){
                            mimeType = "tif";
                        }
                    }
                    if(mimeType.contains("png")){
                        mimeType ="png";
                    }
                    else if( mimeType.contains("jpg")||mimeType.contains("jpeg")){
                        mimeType = "jpg";
                    }
                    else if (mimeType.contains("pdf")){
                        mimeType ="pdf";
                    }
                    else if(mimeType.contains("tif")||mimeType.contains("tiff")){
                        mimeType = "tif";
                    }

                    currentImageType = ImageType.fromValue(mimeType);
                }

回答by monojohnny

Expanding on Birkan's answer, there is a list of 'magic numbers' available here:

扩展 Birkan 的答案,这里有一个“幻数”列表:

http://www.astro.keele.ac.uk/oldusers/rno/Computing/File_magic.html

http://www.astro.keele.ac.uk/oldusers/rno/Computing/File_magic.html

I just checked a BMP and TIFF file (both just created in Windows XP / Paint), and they appear to be correct:

我刚刚检查了一个 BMP 和 TIFF 文件(都是在 Windows XP/Paint 中创建的),它们似乎是正确的:

First two bytes "42 4d" -> BMP
First four bytes "4d 4d 00 2a" -> TIFF

I used VIM to edit the files and then did Tools | Convert to Hex, but you can also use 'od -c' or something similar to check them.

我用 VIM 编辑文件,然后做了 Tools | 转换为十六进制,但您也可以使用 'od -c' 或类似的东西来检查它们。

As a complete aside, I was slightly amused when I found out the magic numbers used for compiled Java Classes: 'ca fe ba be' - 'cafe babe' :)

顺便说一句,当我发现用于编译的 Java 类的神奇数字时,我有点被逗乐了:'ca fe ba be' - 'cafe babe' :)

回答by ArturoTena

Try using the standard JavaBeans Activation Framework(JAF)

尝试使用标准的JavaBeans Activation Framework(JAF)

With the JavaBeans Activation Framework standard extension, developers who use Java technology can take advantage of standard services to determine the type of an arbitrary piece of data, encapsulate access to it, discover the operations available on it, and to instantiate the appropriate bean to perform said operation(s). For example, if a browser obtained a JPEG image, this framework would enable the browser to identify that stream of data as an JPEG image, and from that type, the browser could locate and instantiate an object that could manipulate, or view that image.

通过 JavaBeans Activation Framework 标准扩展,使用 Java 技术的开发人员可以利用标准服务来确定任意数据的类型、封装对它的访问、发现对它的可用操作,并实例化适当的 bean 以执行所述操作。例如,如果浏览器获得了 JPEG 图像,该框架将使浏览器能够将该数据流识别为 JPEG 图像,并且从该类型中,浏览器可以定位和实例化可以操作或查看该图像的对象。