检查文件是否是图像

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

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

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

有人知道吗?

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

http://www.jmagick.org

我一直在使用Image Magick,包括命令行中的“识别”function,它一旦识别图片就永远不会失败。

回到我绝对需要该function且JMagick不存在的日子我已经习惯了Runtime.exec() ImageMagick来自Java的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 

尝试使用图像的宽度:

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

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

为了判断某事是否是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; } 

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

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

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

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

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

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

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

扩展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编辑文件,然后使用Tools | 转换为hex,但您也可以使用’od -c’或类似的东西来检查它们。

总而言之,当我发现用于编译Java类的神奇数字时,我有点觉得好笑:’ca fe ba be’ – ‘cafe babe’:)

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

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

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