前端时间项目中遇到在部分机型上拍照照片加上水印效果后,存储图片旋转了90度的问题。
解决这个问题需要用到android提供的ExifInterface。
ExifInterface是什么?
ExifInterface是Android系统在2.0以后,媒体库加入操作图片Exif的类,Exif是可交换图像文件格式,是专门为数码相机的照片而设定的,可以记录数码照片的属性信息和拍摄数据。简单点说就是保存照片信息的类 包括拍摄的光圈、快门、平衡白、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码以及GPS等。
ExifInterface官方api说明
使用
- ExifInterface既然是保存照片信息的,那么我们在有需要的时候就可以通过这类,来获取照片的一些数码参数来做适当来逻辑处理,比较典型的案例就是android有的机型拍照或者选择照片后,照片可能会被旋转。这个时候我们就可以通过这个类来获取图片的旋转角度信息了。
// 从指定路径下读取图片,并获取其EXIF信息。这里传入需要获取图片的sd卡路径
private int getBitmapDegree(String path) {
int degree = 0;
try {
// 从指定路径下读取图片,并获取其EXIF信息
ExifInterface exifInterface = new ExifInterface(path);
// 获取图片的旋转信息
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
}
常用方法
- String getAttribute(String tag):获取图片中属性为tag的字符串值。
- double getAttribute(String tag,double defaultValue):获取图片中属性为tag的double值。
- int getAttributeInt(String tag,defaultValue):获取图片中属性为tag的int值。
- void setAttribute(String tag,String value):根据输入参数,设定图片Exif的值。
- void saveAttrubutes():把内存中图片的Exif写入到图片中
可以看到,上面大部分方法操作了一个String类型的tag参数,此为Exif的属性,在ExifInterface中定义了一些字符串的静态常量表示这些tag值,常用如下:
- TAG_APERTURE:光圈值。
- TAG_DATETIME:拍摄时间,取决于设备设置的时间。
- TAG_EXPOSURE_TIME:曝光时间。
- TAG_FLASH:闪光灯。
- TAG_FOCAL_LENGTH:焦距。
- TAG_IMAGE_LENGTH:图片高度。
- TAG_IMAGE_WIDTH:图片宽度。
- TAG_ISO:ISO。
- TAG_MAKE:设备品牌。
- TAG_MODEL:设备型号,整形表示,在ExifInterface中有常量对应表示。
- TAG_ORIENTATION:旋转角度,整形表示,在ExifInterface中有常量对应表示。
//获取参数值
ExifInterface exifInterface = new ExifInterface(
7 "/sdcard/a.jpg");
8 String FFNumber = exifInterface
9 .getAttribute(ExifInterface.TAG_APERTURE);
10 String FDateTime = exifInterface
11 .getAttribute(ExifInterface.TAG_DATETIME);
12 String FExposureTime = exifInterface
13 .getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
14 String FFlash = exifInterface
15 .getAttribute(ExifInterface.TAG_FLASH);
16 String FFocalLength = exifInterface
17 .getAttribute(ExifInterface.TAG_FOCAL_LENGTH);
18 String FImageLength = exifInterface
19 .getAttribute(ExifInterface.TAG_IMAGE_LENGTH);
20 String FImageWidth = exifInterface
21 .getAttribute(ExifInterface.TAG_IMAGE_WIDTH);
22 String FISOSpeedRatings = exifInterface
23 .getAttribute(ExifInterface.TAG_ISO);
24 String FMake = exifInterface
25 .getAttribute(ExifInterface.TAG_MAKE);
26 String FModel = exifInterface
27 .getAttribute(ExifInterface.TAG_MODEL);
28 String FOrientation = exifInterface
29 .getAttribute(ExifInterface.TAG_ORIENTATION);
30 String FWhiteBalance = exifInterface
31 .getAttribute(ExifInterface.TAG_WHITE_BALANCE);
回到原问题,系统存储图片与取出图片使用的是同一个旋转值,这样对应的是不会出现问题的,但是我们添加水印后再保存图片由于没有设置这个旋转值,所以图片会出现旋转。
修改这个问题先要通过
/**
* 获取图片的旋转角度
*
* @Title: readPictureDegree
* @param path
* @return
* @return int
* @date 2012-12-4 上午9:22:33
*/
private static int readPictureDegree(String path) {
int orientation = 0;
try {
ExifInterface exifInterface = new ExifInterface(path);
orientation = exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
} catch (IOException e) {
e.printStackTrace();
}
return orientation;
}
获取当前图片的旋转角度,然后再存储图片前再通过
/**
* 将图片的旋转角度进行设置
*
* @Title: setPictureDegreeZero
* @param path
* @return void
* @date 2012-12-10 上午10:54:46
*/
private static void setPictureDegreeZero(String path, String d) {
try {
ExifInterface exifInterface = new ExifInterface(path);
// 修正图片的旋转角度,设置其不旋转。这里也可以设置其旋转的角度,可以传值过去,
// 例如旋转90度,传值ExifInterface.ORIENTATION_ROTATE_90,需要将这个值转换为String类型的
exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, d);
exifInterface.saveAttributes();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
传入设置的值,这样存储的图片就与系统的角度对应起来了。