本文实例讲述了Android开发之使用ExifInterface获取拍照后的图片属性。分享给大家供大家参考,具体如下:

ExifInterface exif = new ExifInterface(file.getPath());

String widthStr = exif.getAttribute(ExifInterface.TAG_IMAGE_WIDTH);

String heightStr = exif.getAttribute(ExifInterface.TAG_IMAGE_LENGTH);

......

/*

* Copyright (C) 2007 The Android Open Source Project

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package android.media;

import java.io.IOException;

import java.text.ParsePosition;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

import java.util.TimeZone;

/**

* This is a class for reading and writing Exif tags in a JPEG file.

*/

public class ExifInterface {

// The Exif tag names

/** Type is int. */

public static final String TAG_ORIENTATION = "Orientation";

/** Type is String. */

public static final String TAG_DATETIME = "DateTime";

/** Type is String. */

public static final String TAG_MAKE = "Make";

/** Type is String. */

public static final String TAG_MODEL = "Model";

/** Type is int. */

public static final String TAG_FLASH = "Flash";

/** Type is int. */

public static final String TAG_IMAGE_WIDTH = "ImageWidth";

/** Type is int. */

public static final String TAG_IMAGE_LENGTH = "ImageLength";

/** String. Format is "num1/denom1,num2/denom2,num3/denom3". */

public static final String TAG_GPS_LATITUDE = "GPSLatitude";

/** String. Format is "num1/denom1,num2/denom2,num3/denom3". */

public static final String TAG_GPS_LONGITUDE = "GPSLongitude";

/** Type is String. */

public static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef";

/** Type is String. */

public static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef";

/** Type is String. */

public static final String TAG_GPS_TIMESTAMP = "GPSTimeStamp";

/** Type is String. */

public static final String TAG_GPS_DATESTAMP = "GPSDateStamp";

/** Type is int. */

public static final String TAG_WHITE_BALANCE = "WhiteBalance";

/** Type is rational. */

public static final String TAG_FOCAL_LENGTH = "FocalLength";

/** Type is String. Name of GPS processing method used for location finding. */

public static final String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod";

// Constants used for the Orientation Exif tag.

public static final int ORIENTATION_UNDEFINED = 0;

public static final int ORIENTATION_NORMAL = 1;

public static final int ORIENTATION_FLIP_HORIZONTAL = 2; // left right reversed mirror

public static final int ORIENTATION_ROTATE_180 = 3;

public static final int ORIENTATION_FLIP_VERTICAL = 4; // upside down mirror

public static final int ORIENTATION_TRANSPOSE = 5; // flipped about top-left bottom-right axis

public static final int ORIENTATION_ROTATE_90 = 6; // rotate 90 cw to right it

public static final int ORIENTATION_TRANSVERSE = 7; // flipped about top-right bottom-left axis

public static final int ORIENTATION_ROTATE_270 = 8; // rotate 270 to right it

// Constants used for white balance

public static final int WHITEBALANCE_AUTO = 0;

public static final int WHITEBALANCE_MANUAL = 1;

private static SimpleDateFormat sFormatter;

static {

System.loadLibrary("exif");

sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");

sFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));

}

private String mFilename;

private HashMap mAttributes;

private boolean mHasThumbnail;

// Because the underlying implementation (jhead) uses static variables,

// there can only be one user at a time for the native functions (and

// they cannot keep state in the native code across function calls). We

// use sLock to serialize the accesses.

private static Object sLock = new Object();

/**

* Reads Exif tags from the specified JPEG file.

*/

public ExifInterface(String filename) throws IOException {

mFilename = filename;

loadAttributes();

}

/**

* Returns the value of the specified tag or {@code null} if there

* is no such tag in the JPEG file.

*

* @param tag the name of the tag.

*/

public String getAttribute(String tag) {

return mAttributes.get(tag);

}

/**

* Returns the integer value of the specified tag. If there is no such tag

* in the JPEG file or the value cannot be parsed as integer, return

* defaultValue.

*

* @param tag the name of the tag.

* @param defaultValue the value to return if the tag is not available.

*/

public int getAttributeInt(String tag, int defaultValue) {

String value = mAttributes.get(tag);

if (value == null) return defaultValue;

try {

return Integer.valueOf(value);

} catch (NumberFormatException ex) {

return defaultValue;

}

}

/**

* Returns the double value of the specified rational tag. If there is no

* such tag in the JPEG file or the value cannot be parsed as double, return

* defaultValue.

*

* @param tag the name of the tag.

* @param defaultValue the value to return if the tag is not available.

*/

public double getAttributeDouble(String tag, double defaultValue) {

String value = mAttributes.get(tag);

if (value == null) return defaultValue;

try {

int index = value.indexOf("/");

if (index == -1) return defaultValue;

double denom = Double.parseDouble(value.substring(index + 1));

if (denom == 0) return defaultValue;

double num = Double.parseDouble(value.substring(0, index));

return num / denom;

} catch (NumberFormatException ex) {

return defaultValue;

}

}

/**

* Set the value of the specified tag.

*

* @param tag the name of the tag.

* @param value the value of the tag.

*/

public void setAttribute(String tag, String value) {

mAttributes.put(tag, value);

}

/**

* Initialize mAttributes with the attributes from the file mFilename.

*

* mAttributes is a HashMap which stores the Exif attributes of the file.

* The key is the standard tag name and the value is the tag's value: e.g.

* Model -> Nikon. Numeric values are stored as strings.

*

* This function also initialize mHasThumbnail to indicate whether the

* file has a thumbnail inside.

*/

private void loadAttributes() throws IOException {

// format of string passed from native C code:

// "attrCnt attr1=valueLen value1attr2=value2Len value2..."

// example:

// "4 attrPtr ImageLength=4 1024Model=6 FooImageWidth=4 1280Make=3 FOO"

mAttributes = new HashMap();

String attrStr;

synchronized (sLock) {

attrStr = getAttributesNative(mFilename);

}

// get count

int ptr = attrStr.indexOf(' ');

int count = Integer.parseInt(attrStr.substring(0, ptr));

// skip past the space between item count and the rest of the attributes

++ptr;

for (int i = 0; i < count; i++) {

// extract the attribute name

int equalPos = attrStr.indexOf('=', ptr);

String attrName = attrStr.substring(ptr, equalPos);

ptr = equalPos + 1; // skip past =

// extract the attribute value length

int lenPos = attrStr.indexOf(' ', ptr);

int attrLen = Integer.parseInt(attrStr.substring(ptr, lenPos));

ptr = lenPos + 1; // skip pas the space

// extract the attribute value

String attrValue = attrStr.substring(ptr, ptr + attrLen);

ptr += attrLen;

if (attrName.equals("hasThumbnail")) {

mHasThumbnail = attrValue.equalsIgnoreCase("true");

} else {

mAttributes.put(attrName, attrValue);

}

}

}

/**

* Save the tag data into the JPEG file. This is expensive because it involves

* copying all the JPG data from one file to another and deleting the old file

* and renaming the other. It's best to use {@link #setAttribute(String,String)}

* to set all attributes to write and make a single call rather than multiple

* calls for each attribute.

*/

public void saveAttributes() throws IOException {

// format of string passed to native C code:

// "attrCnt attr1=valueLen value1attr2=value2Len value2..."

// example:

// "4 attrPtr ImageLength=4 1024Model=6 FooImageWidth=4 1280Make=3 FOO"

StringBuilder sb = new StringBuilder();

int size = mAttributes.size();

if (mAttributes.containsKey("hasThumbnail")) {

--size;

}

sb.append(size + " ");

for (Map.Entry iter : mAttributes.entrySet()) {

String key = iter.getKey();

if (key.equals("hasThumbnail")) {

// this is a fake attribute not saved as an exif tag

continue;

}

String val = iter.getValue();

sb.append(key + "=");

sb.append(val.length() + " ");

sb.append(val);

}

String s = sb.toString();

synchronized (sLock) {

saveAttributesNative(mFilename, s);

commitChangesNative(mFilename);

}

}

/**

* Returns true if the JPEG file has a thumbnail.

*/

public boolean hasThumbnail() {

return mHasThumbnail;

}

/**

* Returns the thumbnail inside the JPEG file, or {@code null} if there is no thumbnail.

* The returned data is in JPEG format and can be decoded using

* {@link android.graphics.BitmapFactory#decodeByteArray(byte[],int,int)}

*/

public byte[] getThumbnail() {

synchronized (sLock) {

return getThumbnailNative(mFilename);

}

}

/**

* Stores the latitude and longitude value in a float array. The first element is

* the latitude, and the second element is the longitude. Returns false if the

* Exif tags are not available.

*/

public boolean getLatLong(float output[]) {

String latValue = mAttributes.get(ExifInterface.TAG_GPS_LATITUDE);

String latRef = mAttributes.get(ExifInterface.TAG_GPS_LATITUDE_REF);

String lngValue = mAttributes.get(ExifInterface.TAG_GPS_LONGITUDE);

String lngRef = mAttributes.get(ExifInterface.TAG_GPS_LONGITUDE_REF);

if (latValue != null && latRef != null && lngValue != null && lngRef != null) {

output[0] = convertRationalLatLonToFloat(latValue, latRef);

output[1] = convertRationalLatLonToFloat(lngValue, lngRef);

return true;

} else {

return false;

}

}

/**

* Returns number of milliseconds since Jan. 1, 1970, midnight.

* Returns -1 if the date time information if not available.

* @hide

*/

public long getDateTime() {

String dateTimeString = mAttributes.get(TAG_DATETIME);

if (dateTimeString == null) return -1;

ParsePosition pos = new ParsePosition(0);

try {

Date datetime = sFormatter.parse(dateTimeString, pos);

if (datetime == null) return -1;

return datetime.getTime();

} catch (IllegalArgumentException ex) {

return -1;

}

}

/**

* Returns number of milliseconds since Jan. 1, 1970, midnight UTC.

* Returns -1 if the date time information if not available.

* @hide

*/

public long getGpsDateTime() {

String date = mAttributes.get(TAG_GPS_DATESTAMP);

String time = mAttributes.get(TAG_GPS_TIMESTAMP);

if (date == null || time == null) return -1;

String dateTimeString = date + ' ' + time;

if (dateTimeString == null) return -1;

ParsePosition pos = new ParsePosition(0);

try {

Date datetime = sFormatter.parse(dateTimeString, pos);

if (datetime == null) return -1;

return datetime.getTime();

} catch (IllegalArgumentException ex) {

return -1;

}

}

private static float convertRationalLatLonToFloat(

String rationalString, String ref) {

try {

String [] parts = rationalString.split(",");

String [] pair;

pair = parts[0].split("/");

int degrees = (int) (Float.parseFloat(pair[0].trim())

/ Float.parseFloat(pair[1].trim()));

pair = parts[1].split("/");

int minutes = (int) ((Float.parseFloat(pair[0].trim())

/ Float.parseFloat(pair[1].trim())));

pair = parts[2].split("/");

float seconds = Float.parseFloat(pair[0].trim())

/ Float.parseFloat(pair[1].trim());

float result = degrees + (minutes / 60F) + (seconds / (60F * 60F));

if ((ref.equals("S") || ref.equals("W"))) {

return -result;

}

return result;

} catch (RuntimeException ex) {

// if for whatever reason we can't parse the lat long then return

// null

return 0f;

}

}

private native boolean appendThumbnailNative(String fileName,

String thumbnailFileName);

private native void saveAttributesNative(String fileName,

String compressedAttributes);

private native String getAttributesNative(String fileName);

private native void commitChangesNative(String fileName);

private native byte[] getThumbnailNative(String fileName);

}

更多关于Android开发相关内容感兴趣的读者可查看本站专题:《Android开发入门与进阶教程》及《Android图形与图像处理技巧总结》

希望本文所述对大家Android程序设计有所帮助。

android android 修改 jpg exif 属性,Android开发之使用ExifInterface获取拍照后的图片属性...相关推荐

  1. Android多媒体功能开发(4)——调用系统Activity拍照、选择图片、查看图片、裁剪图片

    一.拍照 拍照界面就是调用系统照相机,动作为MediaStore.ACTION_IMAGE_CAPTURE.生成的照片有三种返回方式: 在调用拍照应用的Intent中通过EXTRA_OUTPUT属性设 ...

  2. Kindeditor 图片粘贴上传后设置图片属性

    之前转载过一篇 Kindeditor 图片粘贴上传(https://blog.csdn.net/Dongguabai/article/details/100116608)的博客.但是还是存在一个问题, ...

  3. android 动态修改菜单,如何在Android的“选项”菜单上更改MenuItem?

    如何在Android的"选项"菜单上更改MenuItem? 我的Activity上有一个选项菜单,带有mymenu.xml"开始". 选择此3000128611 ...

  4. android 按钮修改边框颜色代码,Android CheckBox修改大小、边框颜色,以及自定义CheckBox;...

    CheckBox修改大小: android:scaleX="0.8" android:scaleY="0.8" CheckBox修改边框颜色,注意不是背景色: ...

  5. Android之拍照后删除图片

    以上为做的一个测试,拍摄照片后,android系统会在/storage/emulated/0/Pictures和/storage/emulated/0/DCIM/Camera两个路径下各创建一张照片 ...

  6. Android调取拍照和获取拍照后的照片

     需要调取照相机拍照,但是又不想用第三方,自己去写的时候,却发现有很多坑.比如: 1.拍完照后,如何获取照片? 2.照片获取不到是什么原因? @ContentView(R.layout.activ ...

  7. 【Android 应用开发】Android 工程修改包名流程 ( 修改 applicationId | 修改 package | 修改 R 资源引用 | 修改 BuildConfig 引用 )

    文章目录 一. Android 工程修改包名流程 二. 修改 applicationId 三. 修改 package 包名 四. AndroidManifest.xml 清单文件组件 五. 修改 R ...

  8. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取 Activity 中的所有方法 | 获取方法上的注解 | 获取注解上的注解 | 通过注解属性获取事件信息 )

    文章目录 前言 一.获取 Activity 中的所有方法 二.获取方法上的注解 三.获取注解上的注解 四.通过注解属性获取相关事件信息 前言 Android 依赖注入的核心就是通过反射获取 类 / 方 ...

  9. Android 7.0下拍照和裁剪图片

    Android 7.0下拍照和裁剪图片 最近,公司的APP集中爆发了头像上传中拍照或照片裁剪的bug,让我才意识到及时学习Android新特性是多么重要,一个过去式的APP是无法一直满足日益变化的新需 ...

最新文章

  1. 建议收藏这7个软件,自用良心推荐!
  2. CentOS 7.6安装OpenMPI3.1.0
  3. 005_html文档类型
  4. python tushare获取股票数据并可视化_荐Python获取股票数据及其可视化--基于tushare库...
  5. python时间转换
  6. 删除fedora多余内核:解决每次升级后旧内核还会存在的问题
  7. python 内置方法的时间复杂度
  8. pandas 如何把时间转成index_pandas将字段中的字符类型转化为时间类型,并设置为索引...
  9. db2数据备份到mysql_DB2数据库自动备份详解
  10. Pentium奔腾架构/流水线及其优化
  11. Activiti中的事件监听
  12. 网站Banner图切换效果(flash)
  13. zstuoj 4245 KI的斐波那契
  14. labview 写入mysql_LabVIEW 连接MySQL数据库
  15. 阿里 M8 级大神整理出 SQL 手册:收获不止 SQL 优化,抓住 SQL 的本质
  16. AI自动识别户型图生成数据建模到3DVR场景解决方案
  17. ORACLE 掐头去尾截取中间字符串
  18. Java中表头的边框置为实线_table表格设置边框线为单实线
  19. QuickBooks qbo api transactionlist 获取数据不全的问题
  20. UCF Local Programming Contest 2012(Practice)E. Pete's Pantry 【模拟】

热门文章

  1. Android极光推送,Manifest merger failed with multiple errors, see logs
  2. cesium billboard 设置距离控制可见度
  3. 实验1 熟悉实验环境
  4. 暨南大学计算机复试线2019,暨南大学2019年考研复试分数线
  5. 【剑指offer - C++/Java】2、替换空格
  6. 微服务架构和SOA的区别
  7. 【论文阅读】Deep Adversarial Subspace Clustering
  8. jQuery 简单案例
  9. ACM学习历程—HDU2068 RPG的错排(组合数学)
  10. asp.net读取xml方法