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程序设计有所帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值