【问题标题】:Check if a file is an image检查文件是否为图像
【发布时间】:2011-01-12 15:47:45
【问题描述】:

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

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

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

有人知道吗?

【问题讨论】:

    标签: java image jai


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      有关 API 使用的文档很少,但您可以查看 this working example(有趣的部分在 identifyOneBinary 方法中)。

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          【解决方案4】:

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

          http://www.jmagick.org

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

          在我绝对需要该功能并且 JMagick 还不存在的日子里,我曾经使用来自 Java 的 Runtime.exec()ImageMagick 的 identify 命令,它运行良好。

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

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

          $  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
          

          【讨论】:

            【解决方案5】:

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

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

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

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

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

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

            【讨论】:

              【解决方案6】:

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

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

              【讨论】:

                【解决方案7】:

                尝试使用图片的宽度:

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

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

                【讨论】:

                • 或许直接使用ImageIcon.getIconWidth()也可以?如果图像未成功加载,它至少会返回 -1
                【解决方案8】:

                为了判断某物是否是 png,我在 Android java 中的 sn-p 下面使用了它。

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

                【讨论】:

                • 正是我想要的
                【解决方案9】:
                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);
                                }
                

                【讨论】:

                  猜你喜欢
                  • 2014-11-25
                  • 1970-01-01
                  • 2014-03-11
                  • 2013-01-13
                  • 2013-08-15
                  • 2014-11-15
                  • 2019-02-16
                  • 2013-03-02
                  • 1970-01-01
                  相关资源
                  最近更新 更多