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