Check if a file is an image
I am using JAI and create a file with:
PlanarImage img = JAI.create("fileload", myFilename);
I check before that line if the file exists. But how could I check if the file i开发者_StackOverflow社区s a .bmp or a .tiff or an image file?
Does anyone know?
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:
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.
Back in the days where I absolutely needed that feature and JMagick didn't exist yet I used to Runtime.exec()
ImageMagick's identify
command from Java and it worked perfectly.
Nowadays that JMagick exist this is probably not necessary anymore (but I haven't tried JMagick yet).
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
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.
To tell if something is a png, I've used this below snippet in 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;
}
At the beginning of files, there is an identifying character sequence. For example JPEG files starts with 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
You could use DROID, a tool for file format identification that also offers a Java API, to be used roughly like this:
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 identifyOneBinary
method).
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.
Expanding on Birkan's answer, there is a list of 'magic numbers' available here:
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:
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.
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' :)
Try using the standard 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.
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);
}
精彩评论