Exif是一种图象文件格式,它的数据存储与JPEG格式是完全相同的。实际上Exif格式就是在JPEG格式头部插入了数码照片的信息,包括拍摄时的光圈、快门、白平衡、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码、拍摄时录制的声音以及全球定位系统(GPS)、缩略图等。简单地说,Exif=JPEG+拍摄参数。——百度百科·Exif
实现图片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与坑爹的手机UC
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标签代码,有的话也去掉。