Android开发之使用ExifInterface获取拍照后的图片属性
程序员文章站
2024-02-20 13:29:22
本文实例讲述了android开发之使用exifinterface获取拍照后的图片属性。分享给大家供大家参考,具体如下:
exifinterface exif =...
本文实例讲述了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<string, string> 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 * <var>defaultvalue</var>. * * @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 * <var>defaultvalue</var>. * * @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, string>(); 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<string, string> 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程序设计有所帮助。
上一篇: .net非托管资源的回收方法
下一篇: Java实现SHA1加密代码实例