Java read the image of mimeType method

  • 2021-01-02 21:49:45
  • OfStack

1. Problem description

In project development, we often encounter the problem of type 1 file upload, which is to get the image format. In many cases, many people use suffixes, as shown below.


if(filename.endsWith(".png") || filename.endsWith(".jpg"))
{
  // Save the picture 
}else{
  throw new IOException("Error file format  ! ");
}

However, this method is rather unreliable. We can try to upload zip files, rmvb files, css, js modified suffix names jpg or png, or upload them to the server, which results in dirty data on our server. In addition, for some image files that have been modified with the wrong extension, some browsers may not be able to display the image.

2. Solutions

In the computer system, the file of media type has [identifier], zip, the image itself belongs to the media file, so we can judge whether the image is legal or not by means of codec.

1. Judge the marking method


private static boolean isBMP(byte[] buf){
 byte[] markBuf = "BM".getBytes(); //BMP The first two bytes of an 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 Picture 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 // You can also use this approach 
 return compare(buf, markBuf);
 }

 private static boolean isJPEGHeader(byte[] buf) {
 byte[] markBuf = {(byte) 0xff, (byte) 0xd8}; //JPEG Began to operator  
 return compare(buf, markBuf);
 }
 
 private static boolean isJPEGFooter(byte[] buf)//JPEG terminator 
 {
 byte[] markBuf = {(byte) 0xff, (byte) 0xd9}; 
 return compare(buf, markBuf);
 }

2. Core methods


/**
 *  Retrievable mimeType
 * @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 1 It was read at the last read 8 a byte, So you have 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 1 Comparison of to 
 * @param buf  Identification to be detected 
 * @param markBuf  Identifier byte array 
 * @return  return false The marks do not match 
 */
 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  The length to read 
 * @return  An array of bytes 
 * @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

The normal test


public class ImageType {
 public static void main(String[] args) { 
  String filename = "oschina.jpg";
  String type = getMimeType(filename);
  System.out.println(type);
 }
}

The output

image/jpeg

Modify the extension test

Modify ES39en. jpeg to ES41en. png

Copy oschina.png 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);
      
 }
}

The output

image/jpeg
image/jpeg


Related articles: