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

本文实例讲述了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程序设计有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/430836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Selenium] 最大化或自定义浏览器的大小

driver.manage().window().maximize(); //将浏览器设置为最大化的状态driver.manage().window().setSize(new Dimension(600, 400)); //将浏览器的大小自定义为600*400转载于:https://www.cnblogs.com/MasterMonkInTemple/p/5212721.html

python中如何替换某列特定数值_python 怎么根据两列值,修改对应的某列值,其中一列的为需要修改的列标题...

自己造了些数据&#xff0c;不知道是否符合题主的意思。原始数据&#xff1a;no wrong_item0 001 a1 003 a2 002 b3 004 c处理后结果&#xff1a;Out[1]:no a b c0 001 1 0 02 002 0 1 01 003 1 0 03 004 0 0 1具体代码如下&#xff1a;import pandas as pd# 创建dataframe,或者…

android怎么ota升级,Android OTA升级过程

通过网络或直接本地获取到OTA升级包之后&#xff0c;通过程序就可开始Android的升级。本文描述这一过程。在获取到OTA升级包之后&#xff0c;可以直接通过android.os.RecoverySystem.installPackage()开启OTA升级。RecoverySystem.installPackage()是在API-8之后加入的&#xf…

进阶学习js中的执行上下文

在js中的执行上下文&#xff0c;菜鸟入门基础 这篇文章中我们简单的讲解了js中的上下文&#xff0c;今天我们就更进一步的讲解js中的执行上下文。 1、当遇到变量名和函数名相同的问题。 var a 10; function a(){console.log(1); } a(); //报错 如果你觉得函数a会覆盖变量a那你…

android使碎片切换界面,玩转Android中的碎片Fragment

引言&#xff1a;在Android开发中&#xff0c;我们都知道一些界面的展示经常会用到的就是Activity,但是Activity存在着很大的局限性,比如说手机上的界面显示在平板上面就会发生各种变形的问题,Activity也无法实现局部的数据刷新,所以Android3.0之后出来了Fragment,Fragment通常…

python123阶乘累加_使用多线程计算阶乘累加 1!+2!+3!+...+19!+20!。其中一个线程计算阶乘,另一线程实现累加并输出结果。...

运用多线程的信号灯法进行边加边计算&#xff01;代码如下public class JieChen {public static void main(String args[]){Sum sum new Sum();new Play(sum).start();new Add(sum).start();}}class Play extends Thread{Sum sum;public Play(Sum sum){this.sumsum;}Overridep…

html GPS坐标实现,JavaScript 实现GPS坐标点距离计算(两个经/纬度间的距离计算)...

在LBS(基于位置服务)的一些应用中&#xff0c;有时我们会需要计算两个用户或两个坐标点之间的距离。要解决这类问题&#xff0c;就要了解空间几何的概念并结合数学中在三角函数公式计算两点之间的值。本文介绍基于经度/纬度的&#xff0c;两个坐标点之间的距离计算&#xff0c;…

机器学习基于skcilearn tensorflow电子书_Tensorflow机器学习模型的跨平台上线

本篇文章转载自博客园&#xff0c;作者: 刘建平Pinard在用PMML实现机器学习模型的跨平台上线中&#xff0c;我们讨论了使用PMML文件来实现跨平台模型上线的方法&#xff0c;这个方法当然也适用于tensorflow生成的模型&#xff0c;但是由于tensorflow模型往往较大&#xff0c;使…

html全局浮窗,Html 实现浮动窗口

今天在写一个html代码时&#xff0c;需要用到浮动窗口&#xff0c;通知信息&#xff0c;网站找了一下&#xff0c;代码如下带关闭按钮的浮动窗口代码(全屏漂浮)#fdck {border:1px solid #c0c0c0;margin:0 auto;padding:5px;background:#f0f0f0}关闭欢迎来到营了个销&#xff01…

python数据可视化工具 pandas_Pandas数据可视化工具——Seaborn用法整理(下)

在前一篇文章 Pandas数据可视化工具——Seaborn用法整理(上)&#xff0c;我们了解了如何使用这些Seaborn代码绘制分布图和分类图。在本文中&#xff0c;我们将继续讨论Seaborn提供的一些其他以绘制不同类型统计图的功能&#xff0c;我们将从矩阵图开始讨论。矩阵图矩阵图是一种…

ssm框架里面前端拿HTML写,ssm框架引入Vue,声明式渲染,标签的href拼接字符串

一、引入Vue在官网上下载vue.js。并用1.下载Vue.js&#xff0c;地址&#xff1a;Vue.js下载地址二、通过ajax获取后台参数&#xff0c;使用Vue渲染调用后台control&#xff0c;获取到数据&#xff0c;传到前端&#xff0c;使用Vue进行渲染。//详细分类,使用Vue渲染function fin…

html5 observer api,基于HTML5新特性Mutation Observer实现编辑器的撤销和回退操作

MutationObserver介绍MutationObserver给开发者们提供了一种能在某个范围内的DOM树发生变化时作出适当反应的能力.该API设计用来替换掉在DOM3事件规范中引入的Mutation事件.Mutation Observer(变动观察器)是监视DOM变动的接口。当DOM对象树发生任何变动时&#xff0c;Mutation …

Maven(五)使用Nexus搭建Maven私服

文章装载于&#xff1a;http://blog.csdn.net/jun55xiu/article/details/39497089 Nexus介绍 Nexus是Maven仓库管理器&#xff0c;如果你使用Maven&#xff0c;你可以从Maven中央仓库下载所需要的构件&#xff08;artifact&#xff09;&#xff0c;但这通常不是一个好的做法&am…

python mean dropna_小丸子踏入python之路:python_day05(用Pandas处理泰坦尼克船员获救数据titanic_train.csv)...

泰坦尼克船员获救数据&#xff1a;titanic_train.csv用excel打开数据集。显示如下&#xff1a;写在前边&#xff1a;为了方便以后运用numpy和pandas的库&#xff0c;分别造它们的别名np和pd.import pandas as pd #造pandas的别名为pdimport numpy as np #造numpy的别名为np一、…

计算机学测打多少字,速度测试,一分钟能打多少字?

六、速度测试——检验学习效果经过一段时间的练习&#xff0c;输入速度提高了不少吧&#xff0c;赶快来测试一下现在一分钟可以输入多少英文或汉字。金山打字通2010的“速度测试”功能不仅有基本的“屏幕对照”速度测试&#xff0c;还有“书本对照”测试及要求较高的“同声录入…

HDFS入门(1)

2015.07.12笔记 1.HDFS Distributed File System&#xff08;操作系统实现人机交互&#xff0c;最重要的功能是文件管理&#xff0c;使用文件管理系统&#xff0c;windows、Linux文件管理系统有共性&#xff1a;用户可创建文件/夹&#xff0c;删除&#xff0c;修改权限&#xf…

竞赛图 计算机网络 应用题,我校学子获2020年“中国高校计算机大赛-网络技术挑战赛”全国总决赛一等奖(图)...

近日&#xff0c;2020年“中国高校计算机大赛-网络技术挑战赛”全国总决赛在温州浙南科技城落下帷幕。我校计算机与信息安全学院陈俊彦、雷晓春老师指导的“智载车队”团队(成员&#xff1a;林楷浩、陈澳格、黄湖)在创业先锋C系列中获得全国一等奖&#xff0c;在创新创意A系列中…

python string模块template_Python - 定制pattern的string模板(template) 详解

定制pattern的string模板(template) 详解本文地址: http://blog.csdn.net/caroline_wendy/article/details/28625179string.Template的pattern是一个正则表达式, 可以通过覆盖pattern属性, 定义新的正则表达式.如: 使用新的定界符"{{", 把{{var}}作为变量语法.代码:#…

建立远程桌面连接计算机无密码,win7远程桌面空密码的步骤_win7系统如何设置让远程桌面登录无需密码-win7之家...

在日常工作中&#xff0c;可能经常会使用到远程连接桌面功能&#xff0c;我们要远程桌面的话&#xff0c;通常是要输入密码才可以的&#xff0c;但是有些用户觉得麻烦&#xff0c;那么win7系统如何设置让远程桌面登录无需密码呢&#xff1f;带着大家的这个问题&#xff0c;本文…

android 请求网络异步载入

/*** 封装ProecssDialog对话框**/ public class LoadDialog extends ProgressDialog {private String title "进度对话框";private String message "载入数据中....";public LoadDialog(Context context, int theme) {super(context, theme);}/*** 用默认…