位置: 编程技术 - 正文
推荐整理分享Android:操作图片Exif信息(android 图片),希望有所帮助,仅作参考,欢迎阅读内容。
文章相关热门搜索词:android picture,android选择图片,android自带图片选择器,android 图片按钮,android picture,android图片按钮的图片尺寸,android图片布局,android 图片,内容如对您有帮助,希望把文章链接给更多的朋友!
什么是Exif
先来了解什么是Exif。Exif是一种图像文件式,它的数据存储于JPEG式是完全相同的,实际上Exif式就是JPEG式头插入了数码照片的信息,包括拍摄的光圈、快门、平衡白、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码以及GPS等。简单来说,Exif=拍摄参数JPED。因此,可以利用任何可以查看JPEG文件的看图软件浏览Exif信息,但是并不是所有图形程序都能处理Exif信息,而自Android2.0之后,加入了对图片Exif数据的支持。
ExifInterface
在Android下,通过ExifInterface类操作图片的Exif信息,虽然这个类的名字包含Interface,但它不是一个接口,它是一个类,处于"android.media.ExifInterface"包下,是媒体库的一部分功能的实现。ExifInterface有一个构造函数,接受一个String类型的数据,此为读取图片文件的地址。
Exif数据在图片中可以理解为Key-value键对的方式存储,一般通过如下几个方法操作:
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中有常量对应表示。
以上常量不包括GPS的信息,实际上Exif还可以保存拍摄时GPS的信息,但是需要设备支持。下面通过一个Demo,讲解一下这些参数的获取与的展示:
代码如下:
1 btn_readExifInLog.setOnClickListener(new View.OnClickListener() {
2
3 @Override
4 public void onClick(View v) {
5 try {
6 ExifInterface exifInterface = new ExifInterface(
7 "/sdcard/a.jpg");
8 String FFNumber = exifInterface
9 .getAttribute(ExifInterface.TAG_APERTURE);
String FDateTime = exifInterface
.getAttribute(ExifInterface.TAG_DATETIME);
String FExposureTime = exifInterface
.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
String FFlash = exifInterface
.getAttribute(ExifInterface.TAG_FLASH);
String FFocalLength = exifInterface
.getAttribute(ExifInterface.TAG_FOCAL_LENGTH);
String FImageLength = exifInterface
.getAttribute(ExifInterface.TAG_IMAGE_LENGTH);
String FImageWidth = exifInterface
.getAttribute(ExifInterface.TAG_IMAGE_WIDTH);
String FISOSpeedRatings = exifInterface
.getAttribute(ExifInterface.TAG_ISO);
String FMake = exifInterface
.getAttribute(ExifInterface.TAG_MAKE);
String FModel = exifInterface
.getAttribute(ExifInterface.TAG_MODEL);
String FOrientation = exifInterface
.getAttribute(ExifInterface.TAG_ORIENTATION);
String FWhiteBalance = exifInterface
.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
Log.i(TAG, "FFNumber:" FFNumber);
Log.i(TAG, "FDateTime:" FDateTime);
Log.i(TAG, "FExposureTime:" FExposureTime);
Log.i(TAG, "FFlash:" FFlash);
Log.i(TAG, "FFocalLength:" FFocalLength);
Log.i(TAG, "FImageLength:" FImageLength);
Log.i(TAG, "FImageWidth:" FImageWidth);
Log.i(TAG, "FISOSpeedRatings:" FISOSpeedRatings);
Log.i(TAG, "FMake:" FMake);
Log.i(TAG, "FModel:" FModel);
Log.i(TAG, "FOrientation:" FOrientation);
Log.i(TAG, "FWhiteBalance:" FWhiteBalance);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
获得数据:
操作Exif
上面提到,获取与设置图片的Exif信息,使用到的ExifInterface中的方法,上面已经列举出来了,主要是通过tag指定存储。
这里说明一下,Exif信息在图片中以二进制的形式存储,每个字段存储的数据位数是固定的,并且tag的数量也是固定,所以我们只能操作图片Exif信息中已经存在的tag的,并且保存的数据要依照它存储位数的限制,如果存储的数据类型错误,将会导致存储的数据可能无法正确的取出,超出位数将被截取。如无法将TAG_ORIENTATION中存储一个字符串的数据,它必须存储int类型的,多出来的将被截取。
还有一点需要注意的,saveAttributes()方法主要用于把内存中所有当前Exif信息保存到目标图片中,依照官方文档的解释,它是一个低效率的,它会把图片的所有Exif信息,重新依次保存到目标图片,所以推荐使用setAttribute()方法进行设置Exif信息。但是在实际应用中发现,如果仅使用setAttribute()设置Exif信息,将不会写入到目标图片中,只有在改变Exif信息后,调用saveAttribute()才可以把新的Exif写入到目标图片中。这个过程效率比较低,模拟器上会卡顿一下,但是真机测试没有这样的情况,反应很快。
下面通过一个简单的Demo来演示Exif的保存于读取:
1%btn_saveExif.setOnClickListener(new%View.OnClickListener()%{
2
3%@Override
4%public%void%onClick(View%v)%{
5%try%{
6%//%tag
7%String%strAttr%=%et_attr.getText().toString().trim();
8%//%tag-value
9%String%strValue%=%et_value.getText().toString().trim();
%if%(TextUtils.isEmpty(strAttr)
%||%TextUtils.isEmpty(strValue))%{
%Toast.makeText(MainActivity.this,%"请填写属性及",
%Toast.LENGTH_SHORT).show();
%return;
%}
%//%获取图片Exif
%ExifInterface%exif%=%new%ExifInterface("/sdcard/a.jpg");
// 保存指定tag的
exif.setAttribute(strAttr,strValue);
// 把Exif信息写入目标图片
exif.saveAttributes();
Toast.makeText(MainActivity.this, "Exif信息保存成功",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
});
btn_readExif.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
// tag
String strAttr = et_attr.getText().toString().trim();
if (TextUtils.isEmpty(strAttr)) {
Toast.makeText(MainActivity.this, "请填写属性",
Toast.LENGTH_SHORT).show();
return;
}
// 获取图片Exif
ExifInterface exif = new ExifInterface("/sdcard/a.jpg");
// 获取指定tag的属性
String strValue = exif.getAttribute(strAttr);
if (!TextUtils.isEmpty(strValue)) {
Toast.makeText(MainActivity.this, strAttr"="strValue,
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "图片Exif中没有属性为"strAttr"的信息",
Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
效果展示,先读取Make信息,再写入Make信息并重新读取:
注意,上面示例中,如果Attribute写任意,会提示保存成功,但是并没有写入到目标图片的Exif信息当中。
转自:
android 加载第三方库 LOCAL_PATH:=$(callmy-dir)include$(CLEAR_VARS)LOCAL_MODULE:=calLOCAL_SRC_FILES:=./libcal.soLOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)/../../sum/jni/include$(PREBUILT_SHARED_LIBRARY)include$(CLEAR_VARS)LOCA
Android 事件分发 1、View的事件分发比如说你当前有一个非常简单的项目,只有一个Activity,并且Activity中只有一个按钮。你可能已经知道,如果想要给这个按钮注册一个
android系统架构各层的一些介绍 本内容来自豆瓣。一.android系统架构各层介绍1.应用层:应用是用java语言编写的运行在虚拟机上的程序,比如Email客户端,SMS短消息程序,日历等。2.应
标签: android 图片
本文链接地址:https://www.jiuchutong.com/biancheng/374380.html 转载请保留说明!上一篇:画廊效果,仿百度地图(画廊作品)
友情链接: 武汉网站建设