Exif是一种图象文件格式,它的数据存储与JPEG格式是完全相同的。实际上Exif格式就是在JPEG格式头部插入了数码照片的信息,包括拍摄时的光圈、快门、白平衡、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码、拍摄时录制的声音以及全球定位系统(GPS)、缩略图等。简单地说,Exif=JPEG+拍摄参数。——百度百科·Exif
最近项目中需要获取到用户上传图片的拍摄日期,想起可以使用metadata-extractor解析。这个jar包可以拿到关于图片的很多信息,代码如下:
/** * 图片Exif信息采集 * */ public class ImageExif { public static void main( String[] args ) throws ImageProcessingException, IOException{ File img = new File("图片.jpg"); Metadata meta = JpegMetadataReader.readMetadata(img); for(Directory dir : meta.getDirectories()){ for(Tag tag : dir.getTags()){ String tagName = tag.getTagName(); String description = tag.getDescription(); System.out.printf("%-30s\t%-100s\n", tagName, description); } } } }
执行结果如下:
Compression Type Baseline Data Precision 8 bits Image Height 800 pixels Image Width 532 pixels Number of Components 3 Component 1 Y component: Quantization table 0, Sampling factors 1 horiz/1 vert Component 2 Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert Component 3 Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert Version 1.2 Resolution Units inch X Resolution 72 dots Y Resolution 72 dots Make NIKON CORPORATION Model NIKON D700 Orientation Top, left side (Horizontal / normal) X Resolution 72 dots per inch Y Resolution 72 dots per inch Resolution Unit Inch Software Adobe Photoshop CS3 Windows Date/Time 2010:04:19 10:59:46 Artist MINGGO Copyright MINWT Exposure Time 1/80 sec F-Number F5.6 Exposure Program Manual control ISO Speed Ratings 1600 Exif Version 2.21 Date/Time Original 2010:04:18 11:59:49 Date/Time Digitized 2010:04:18 11:59:49 Shutter Speed Value 1/79 sec Aperture Value F5.6 Exposure Bias Value 0 EV Max Aperture Value F1.7 Metering Mode Spot White Balance Unknown Flash Flash did not fire Focal Length 50.0 mm Sub-Sec Time 56 Sub-Sec Time Original 56 Sub-Sec Time Digitized 56 Color Space sRGB Exif Image Width 532 pixels Exif Image Height 800 pixels Sensing Method One-chip color area sensor File Source Digital Still Camera (DSC) Scene Type Directly photographed image CFA Pattern 2 0 2 0 0 1 1 2 Custom Rendered Normal process Exposure Mode Manual exposure White Balance Mode Auto white balance Digital Zoom Ratio 1 Focal Length 35 50mm Scene Capture Type Portrait Gain Control Low gain down Contrast None Saturation None Sharpness Hard Subject Distance Range Unknown Thumbnail Compression JPEG (old-style) X Resolution 72 dots per inch Y Resolution 72 dots per inch Resolution Unit Inch Thumbnail Offset 898 bytes Thumbnail Length 6474 bytes Lens Information 500/10 500/10 18/10 18/10 Lens 50.0 mm f/1.8 Serial Number 2270203 Make NIKON CORPORATION Model NIKON D700 Exposure Time 1/80 sec Exposure Program Manual control Aperture Value F5.6 F-Number F5.6 Focal Length 50.0 mm Shutter Speed Value 1/79 sec Date/Time Original Sun Apr 18 11:59:49 CST 2010 Date/Time Digitized Sun Apr 18 11:59:49 CST 2010 Rating 0.0 Profile Size 3144 CMM Type Lino Version 2.1.0 Class Display Device Color space RGB Profile Connection Space XYZ Profile Date/Time Mon Mar 09 14:49:00 CST 1998 Signature acsp Primary Platform Microsoft Corporation Device manufacturer IEC Device model sRGB XYZ values 0.9642029 1.0 0.8249054 Tag Count 17 Copyright Copyright (c) 1998 Hewlett-Packard Company Profile Description sRGB IEC61966-2.1 Media White Point (0.9504547, 1.0, 1.0890503) Media Black Point (0.0, 0.0, 0.0) Red Colorant (0.43606567, 0.2224884, 0.013916016) Green Colorant (0.3851471, 0.71687317, 0.097076416) Blue Colorant (0.1430664, 0.06060791, 0.71409607) Device Mfg Description IEC http://www.iec.ch Device Model Description IEC 61966-2.1 Default RGB colour space - sRGB Viewing Conditions Description Reference Viewing Condition in IEC61966-2.1 Viewing Conditions view(0x76696577): 36 bytes Luminance (76.03647, 80.0, 87.12462) Measurement 1931 2° Observer, Backing (0.0, 0.0, 0.0), Geometry Unknown, Flare 1%, Illuminant D65 Technology CRT IPTC-NAA Record 28 bytes binary data Caption Digest -120 115 -64 -22 54 -33 38 23 120 -85 -32 -118 -89 -67 -86 116 Print Info [74 bytes] Resolution Info 72.0x72.0 DPI Print Scale Centered, Scale 1.0 Global Angle 30 Global Altitude 30 Print Flags 0 0 0 0 0 0 0 0 1 Copyright Flag No Print Flags Information 0 1 0 0 0 0 0 0 0 2 Color Halftoning Information [72 bytes] Color Transfer Functions [112 bytes] Grid and Guides Information 0 0 0 1 0 0 2 64 0 0 2 64 0 0 0 0 URL List 0 Slices DSC_3081 (0,0,800,532) 1 Slices Pixel Aspect Ratio 1.0 Seed Number 1 Thumbnail Data JpegRGB, 106x160, Decomp 51200 bytes, 1572865 bpp, 6474 bytes Version Info 1 (Adobe Photoshop, Adobe Photoshop CS3) 1 JPEG Quality 12 (Maximum), Optimised format, 3 scans Application Record Version 97 By-line MINGGO Copyright Notice MINWT DCT Encode Version 1 Flags 0 64 Flags 1 0 Color Transform YCbCr
其中,Date/Time Original对应就是图片拍摄的日期。
这里有一个坑,本来项目采用的是SpringMVC框架,在Controller中实现图片上传,然后解析图片。但问题是,SpringMVC使用MultipartFile来接收前台传过来的文件,这个类和File类不是继承关系。虽然可以讲MultipartFile类通过transferTo方法转换为File类,但这个转换过程会丢失Exif信息。
为了解决这个问题,我放弃了SpringMVC的Controller,改用Servlet实现图片上传功能。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload sfu = new ServletFileUpload(factory); sfu.setHeaderEncoding("UTF-8"); // 处理中文问题 sfu.setSizeMax(1024 * 1024 * 5); // 限制文件大小 int success = 1; try { // 解码请求 List<FileItem> fileItems = sfu.parseRequest(request); // 得到所有表单元素 for (FileItem fi : fileItems) { // 有可能是文件,也可能是普通表单 if (!fi.isFormField()) { String fileName = fi.getName(); File file = new File("D:\\upload", fileName); fi.write(file); } } } catch (Exception e) { e.printStackTrace(); success = 0; } Map<String, Object> result = new HashMap<String, Object>(); result.put("success", success); result.put("url", fileName); response.getWriter().write(JsonUtil.writeObj2JSON(result)); }
文件上传是项目中经常会遇到的需求,文件上传的表单在前台表现为type为file的input标签。对于包裹这个input的form标签,需要定义其method属性为POST,另外需要指定enctype="multipart/form-data"。这二者缺其一,后台都无法接收到上传的文件,如果使用的SpringMVC,同时使用MultipartFile接收文件,甚至会报异常。
ajaxfileupload.js能够帮助我们完成图片上传的页面工作,使用它我们就可以不用理会什么method为POST、enctype属性等问题,只需要在页面放置一个file input即可。可以想见的是,ajaxfileupload的工作原理即为将指定的file input通过js脚本封装到一个form表单中,同时它会自动完成必备的条件,比如enctype属性。
使用ajaxfileupload需要以下步骤:
引入jquery.min.js与ajaxfileupload.js文件;
在html代码中放置一个file input,并指定id;
编写文件上传代码及上传完成后的回调函数。
代码实现如下:
<!doctype html> <html> <head> <meta charset="UTF-8" /> <title>AjaxFileUpload</title> </head> <body> <input type="file" name="file" id="file"/> <script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script> <script src="js/ajaxfileupload.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $(function(){ $('#file').on('change', function(){ $.ajaxFileUpload({ url:'image_upload.do', secureuri :false, fileElementId :'file', // file input的id值 dataType:'text', success : function (data, status){ data = data.replace(/^<pre.*>(.*)<\/pre>$/g, '$1'); alert('图片上传成功'); }, error: function(data, status, e){ alert('图片上传失败'); } }); }); }); </script> </body> </html>
需要注意的是,在success回调函数中,返回的数据data,会被pre标签包裹,所以在使用之前需要将pre标签去掉。为什么说手机UC浏览器坑爹呢,是因为即便去掉这个pre标签,手机UC浏览器还是会在返回的data后追加一段script脚本,所以最好判断下,是否有script标签代码,有的话也去掉。