Java图片上传与EXIF信息采集


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需要以下步骤:

  1. 引入jquery.min.js与ajaxfileupload.js文件;

  2. 在html代码中放置一个file input,并指定id;

  3. 编写文件上传代码及上传完成后的回调函数。

代码实现如下:

<!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标签代码,有的话也去掉。

你可能感兴趣的:(Java图片上传与EXIF信息采集)