一直经过一些图片模块来取得图片的相关信息,最近在使用的过程当中打开源码看了一下,学习到了很多东西。javascript
首先,一个文件的基本信息都是存在于文件自身,即便压缩工具会去掉一些信息,但基本的文件类型,宽,高等都还会存在,因此,咱们须要知道这些信息具体存在于哪一个位置上。php
经过相关搜索,咱们获得了以下的信息:css
能够看到,几乎全部的文件起始位置存放的都是 文件类型
,jpg 有三种 16 进制标记,png 只有一种,也就是说,我只须要以下判断,就能够知道文件是什么文件。java
function getFileType(buffer){ if(buffer_data[0] == 0x89 && buffer_data[1] == 0x50 && buffer_data[2] == 0x4E && buffer_data[3] == 0x47 && buffer_data[4] == 0x0D && buffer_data[5] == 0x0A && buffer_data[6] == 0x1A && buffer_data[7] == 0x0A){ return 'png'; }else if(){ //... } }
严谨完整的判断应该是如上的代码,但经过观察整个列表,其实会发现,不少信息都是惟一的,好比 jpg 有三种,但三种的前三位都是 FF D8 FF
, 并且其余类型的文件都没有与其同样的,因此,能够不须要写那么长的判断,只需判断前三位便可。git
附: 完整的 Hex signature 列表:https://en.wikipedia.org/wiki/List_of_file_signaturesgithub
那图片的宽高信息又存在于哪些位置呢?不一样类型的文件,宽高信息存储的位置都不同,如 png 的 hex 信息以下:gulp
第 17 到 20 字节区间的位置存储着 png 的宽度信息,经过将其转换为 10 进制,就能够获得咱们要的宽度值了。
如: 16 进制的 0000005A
转换为 10 进制为 90
。工具
知道原理后,若是只是想简单的获得图片的一些基本信息,只须要写一点代码就能够很是高性能的获取,而不须要去依赖一些稍重的图形模块。
具体代码能够查看: https://github.com/weixin/gulp-lazyimagecss/blob/master/lib/fastimagesize.js性能
知道原理后,也能够联想到更多,好比,.png 有可能并非 png,有多是其余; 若是一个图片上传模块验证不够完美,我把一个 php 文件的头改成图片头,欺骗了程序进行上传后执行,结果就有可能 呵呵 了。学习
文件的 hex 值能够经过一些 hex 工具查看,好比 sublime 就有 hex viewer 插件。