1. Problem description
During project development, we often encounter a problem of uploading files, which is the format of the image to obtain. In many cases, many people use the suffix name to judge, as shown below.
if(filename.endsWith(".png") || filename.endsWith(".jpg")){ //Save the picture}else{ throw new IOException("Error file format!");}However, this method is quite unreliable. We can try to upload the zip file, rmvb file, css, js to modify the suffix name jpg or png, or upload it to the server, which causes dirty data to appear on our server. In addition, for some image files, if they are modified to the wrong extension, some browsers may not be able to display the image.
2. Solution
In computer systems, media type files have [identifiers], and zip and pictures themselves belong to media files, so we can determine whether the pictures are legal through encoding and decoding.
1. Method of judging and marking
private static boolean isBMP(byte[] buf){ byte[] markBuf = "BM".getBytes(); //The first two bytes of the BMP image file return compare(buf, markBuf); } private static boolean isICON(byte[] buf) { byte[] markBuf = {0, 0, 1, 0, 1, 0, 32, 32}; return compare(buf, markBuf); } private static boolean isWEBP(byte[] buf) { byte[] markBuf = "RIFF".getBytes(); //WebP image identifier return compare(buf, markBuf); } private static boolean isGIF(byte[] buf) { byte[] markBuf = "GIF89a".getBytes(); //GIF identifier if(compare(buf, markBuf)) { return true; } markBuf = "GIF87a".getBytes(); //GIF identifier if(compare(buf, markBuf)) { return true; } return false; } private static boolean isPNG(byte[] buf) { byte[] markBuf = {(byte) 0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A}; //PNG identifier// new String(buf).indexOf("PNG")>0 //This method can also be used to return compare(buf, markBuf); } private static boolean isJPEGHeader(byte[] buf) { byte[] markBuf = {(byte) 0xff, (byte) 0xd8}; //JPEG start character return compare(buf, markBuf); } private static boolean isJPEGFooter(byte[] buf)//JPEG ending character { byte[] markBuf = {(byte) 0xff, (byte) 0xd9}; return compare(buf, markBuf); }2. Core Methods
/** * Get the mimeType of the file * @param filename * @return */ private static String getMimeType(String filename){ try { String mimeType = readType(filename); return String.format("image/%s", mimeType); } catch (IOException e) { e.printStackTrace(); } return null; } /** * Read file type* @param filename * @return * @throws IOException */ private static String readType(String filename) throws IOException { FileInputStream fis = null; try { File f = new File(filename); if(!f.exists() || f.isDirectory() || f.length()<8) { throw new IOException("the file ["+f.getAbsolutePath()+"] is not image !"); } fis= new FileInputStream(f); byte[] bufHeaders = readInputStreamAt(fis,0,8); if(isJPEGHeader(bufHeaders)) { long skiplength = f.length()-2-8; //The first time I read 8 bytes, so I need to subtract byte[] bufFooters = readInputStreamAt(fis, skiplength, 2); if(isJPEGFooter(bufFooters)) { return "jpeg"; } } if(isPNG(bufHeaders)) { return "png"; } if(isGIF(bufHeaders)) { return "gif"; } if(isWEBP(bufHeaders)) { return "webp"; } if(isBMP(bufHeaders)) { return "bmp"; } if(isICON(bufHeaders)) { return "ico"; } throw new IOException("the image's format is unkown!"); } catch (FileNotFoundException e) { throw e; } finally{ try { if(fis!=null) fis.close(); } catch (Exception e) { } } } /** * Mark consistency comparison* @param buf Mark to be detected* @param markBuf Identifier byte array* @return Return false Mark sign mismatch*/ private static boolean compare(byte[] buf, byte[] markBuf) { for (int i = 0; i < markBuf.length; i++) { byte b = markBuf[i]; byte a = buf[i]; if(a!=b){ return false; } } return true; } /** * * @param fis Input stream object* @param skiplength Skip position length* @param length Length to read* @return Byte array* @throws IOException */ private static byte[] readInputStreamAt(FileInputStream fis, long skiplength, int length) throws IOException { byte[] buf = new byte[length]; fis.skip(skiplength); // int read = fis.read(buf,0,length); return buf; }3. Test code
Normal test
public class ImageType { public static void main(String[] args) { String filename = "oschina.jpg"; String type = getMimeType(filename); System.out.println(type); }} Output
image/jpeg
Modify extension test
① Modify oschina.jpeg to oschina.png
②Copy oschina.png to delete the extension
public class ImageType { public static void main(String[] args) { String filename = "oschina.png"; String type = getMimeType(filename); System.out.println(type); filename = "oschina"; type = getMimeType(filename); System.out.println(type); }} Output
image/jpeg
image/jpeg
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.