我正在使用 JAI 并创建一个文件:
PlanarImage img = JAI.create("fileload", myFilename);
如果文件存在,我会在该行之前检查。但是我如何检查文件是 .bmp 或 .tiff 还是图像文件?
有人知道吗?
Image Magick 项目具有识别图像的设施,并且有一个名为 JMagick 的 Image Magick 的 Java 包装器,我认为您可能需要考虑而不是重新发明轮子:
我一直在使用 Image Magick,包括它在命令行中的“识别”功能,而且它从来没有失败过一次识别图片。
回到我绝对需要该功能并且 JMagick 还不存在的日子里,我曾经使用Java 中Runtime.exec()
的 ImageMagickidentify
命令并且它运行良好。
现在 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;
}
您可以使用DROID,这是一种文件格式识别工具,还提供 Java API,大致如下使用:
AnalysisController controller = new AnalysisController();
controller.readSigFile(signatureFileLocation);
controller.addFile(fileToIdentify.getAbsolutePath());
controller.runFileFormatAnalysis();
Iterator<IdentificationFile> it = controller.getFileCollection().getIterator();
关于 API 使用的文档相当稀少,但您可以查看这个工作示例(有趣的部分在identifyOneBinary
方法中)。
在文件的开头,有一个识别字符序列。例如 JPEG 文件以 FF D8 FF 开头。
您可以在程序中检查此序列,但我不确定这是否适用于每个文件。
有关识别字符的信息,您可以查看http://fileext.com
确定文件内容的唯一(半)可靠方法是打开文件并读取前几个字符。然后,您可以使用一组测试,例如在 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 编辑文件,然后使用工具 | 转换为十六进制,但您也可以使用 'od -c' 或类似的东西来检查它们。
顺便说一句,当我发现用于编译的 Java 类的神奇数字时,我有点好笑:'ca fe ba be' - 'cafe babe' :)
尝试使用标准的JavaBeans 激活框架(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);
}