Java 读取图片的mimeType的方法
程序员文章站
2023-12-13 11:52:10
一、问题描述
在项目开发的时候,我们经常会遇到一类文件上传的问题,就是获取图片是哪种格式。很多情况下,很多人都是用后缀名去判断,如下所示。
if(filenam...
一、问题描述
在项目开发的时候,我们经常会遇到一类文件上传的问题,就是获取图片是哪种格式。很多情况下,很多人都是用后缀名去判断,如下所示。
if(filename.endswith(".png") || filename.endswith(".jpg")) { //保存图片 }else{ throw new ioexception("error file format !"); }
但是这种方式相当不可靠,我们可以尝试将zip文件、rmvb文件、css、js修改后缀名位jpg或者png上传,也可以上传到服务器,这就造成我们服务器上出现了脏数据。此外,对于有些图片文件,修改成错误的扩展名,有些浏览器可能无法显示出此图片。
二、解决方案
在计算机系统中,媒体类型的文件都有【标识符】,zip、图片本身属于媒体文件,因此我们可以通过编解码的方式判断图片是否合法。
1、判断标示方法
private static boolean isbmp(byte[] buf){ byte[] markbuf = "bm".getbytes(); //bmp图片文件的前两个字节 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图片识别符 return compare(buf, markbuf); } private static boolean isgif(byte[] buf) { byte[] markbuf = "gif89a".getbytes(); //gif识别符 if(compare(buf, markbuf)) { return true; } markbuf = "gif87a".getbytes(); //gif识别符 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识别符 // new string(buf).indexof("png")>0 //也可以使用这种方式 return compare(buf, markbuf); } private static boolean isjpegheader(byte[] buf) { byte[] markbuf = {(byte) 0xff, (byte) 0xd8}; //jpeg开始符 return compare(buf, markbuf); } private static boolean isjpegfooter(byte[] buf)//jpeg结束符 { byte[] markbuf = {(byte) 0xff, (byte) 0xd9}; return compare(buf, markbuf); }
2、核心方法
/** * 获取文件的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; } /** * 读取文件类型 * @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; //第一次读取时已经读了8个byte,因此需要减掉 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) { } } } /** * 标示一致性比较 * @param buf 待检测标示 * @param markbuf 标识符字节数组 * @return 返回false标示标示不匹配 */ 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 输入流对象 * @param skiplength 跳过位置长度 * @param length 要读取的长度 * @return 字节数组 * @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、测试代码
正常测试
public class imagetype { public static void main(string[] args) { string filename = "oschina.jpg"; string type = getmimetype(filename); system.out.println(type); } }
输出
image/jpeg
修改扩展名测试
①修改oschina.jpeg为oschina.png
②复制oschina.png删除扩展名
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); } }
输出
image/jpeg
image/jpeg
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。