Android之exif格式 ExifInterface

weixin_33976072發表於2018-05-02

什麼是exif?

Exif是一種影像檔案格式,它的資料儲存與JPEG格式是完全相同的。實際上Exif格式就是在JPEG格式頭部插入了數碼照片的資訊,包括拍攝時的光圈快門白平衡ISO焦距、日期時間等各種和拍攝條件以及相機品牌、型號、色彩編碼、拍攝時錄製的聲音以及GPS全球定位系統資料、縮圖等。你可以利用任何可以檢視JPEG檔案的看圖軟體瀏覽Exif格式的照片,但並不是所有的圖形程式都能處理Exif資訊。

簡單來說,Exif 資訊就是由數位相機在拍攝過程中採集一系列的資訊,然後把資訊放置在我們熟知的 JPEG/TIFF 檔案的頭部,也就是說 Exif資訊是鑲嵌在 JPEG/TIFF 影像檔案格式內的一組拍攝引數,它就好像是傻瓜相機的日期列印功能一樣,只不過 Exif資訊所記錄的資訊更為詳盡和完備。Exif 所記錄的後設資料資訊非常豐富,主要包含了以下幾類資訊:

  • 拍攝日期

  • 拍攝器材(機身、鏡頭、閃光燈等)

  • 拍攝引數(快門速度、光圈F值、ISO速度、焦距、測光模式等)

  • 影像處理引數(銳化、對比度、飽和度、白平衡等)

  • 影像描述及版權資訊

  • GPS定位資料

  • 縮圖

常見標籤

| 標籤號 | Exif 定義名 | 中文定義名 | 備註 |
| 0x010E| ImageDescription | 影像描述 | - |
| 0x013B | Artist | 作者 | 使用者的名字 |
| 0x010F | Make | 生產商 | 相機生產廠家 |
| 0x0110 | Model | 型號 | 相機型號 |
| 0x0112 | Orientation | 方向 | 有的相機支援,有的不支援 |
| 0x011A | XResolution | 水平方向解析度 | - |
| 0x011B | YResolution | 垂直方向解析度 | - |
| 0x0128 | ResolutionUnit | 解析度單位 | - |
| 0x0131 | Software | 軟體 | 韌體Firmware版本或編輯軟體 |
| 0x0132 | DateTime | 日期和時間 | 照片最後的修改時間 |
| 0x0213 | YCbCrPositioning | YCbCr定位 | 色度抽樣方法 |
| 0x8769 | ExifOffset | Exif子IFD偏移量 | - |
| 0x829A | ExposureTime | 曝光時間 | 即快門速度 |
| 0x829D | FNumber | 光圈係數 | 光圈的F值 |
| 0x8822 | ExposureProgram | 曝光程式 | 自動曝光、光圈優先、快門優先、M檔等 |
| 0x8827 | ISOSpeedRatings | ISO感光度 | Exif 2.3 中更新為“PhotographicSensitivity” |
| 0x9000 | ExifVersion | Exif 版本 | 參見“歷史版本”一節 |
| 0x9003 | DateTimeOriginal | 拍攝時間 | 照片拍攝的時間 |
| 0x9004 | DateTimeDigitized | 數字化時間 | 照片被寫入記憶體卡的時間 |
| 0x9204 | ExposureBiasValue | 曝光補償 | - |
| 0x9205 | MaxApertureValue | 最大光圈 | APEX為單位 |
| 0x9207 | MeteringMode | 測光模式 | 平均測光、中央重點測光、點測光等 |
| 0x9208 | Lightsource | 光源 | 一般記錄白平衡設定 |
| 0x9209 | Flash | 閃光燈 | 記錄閃光燈狀態 |
| 0x920A | FocalLength | 鏡頭焦距 | 鏡頭物理焦距 |
| 0x927C | MakerNote | 廠商註釋 | 參見“廠商註釋”一節 |
| 0x9286 | UserComment | 使用者註釋 | 使用者自定義資料 |
| 0xA000 | FlashPixVersion | FlashPix版本 | - |
| 0xA001 | ColorSpace | 色彩空間 | 一般為sRGB |
| 0xA002 | ExifImageWidth | 影像寬度 | 影像橫向畫素數 |
| 0xA003 | ExifImageLength | 影像高度 | 影像縱向畫素數 |
| 0xA433 | LensMake | 鏡頭生產商 | - |
| 0xA434 | LensModel | 鏡頭型號 | - |

Android 之 操作Exif的類ExifInterface

一個在JPEG檔案或RAW影像檔案中讀寫Exif標籤的類
支援的格式有:JPEG, DNG, CR2, NEF, NRW, ARW, RW2, ORF and RAF。

獲取資訊

獲取Exif資訊大致有以下一些方法:

  • 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寫入到圖片中。

ExifInterface類中封裝了很多tag,這些tag就是Exif中標籤,根據上面的方法就能獲取某個標籤的值,感覺這些個標籤的值是以key-value形式儲存的。
下面給出常用的一些標籤:

  • ExifInterface.TAG_ORIENTATION //旋轉角度,整形表示,在ExifInterface中有常量對應表示
  • ExifInterface.TAG_DATETIME //拍攝時間,取決於裝置設定的時間
  • ExifInterface.TAG_MAKE //裝置品牌
  • ExifInterface.TAG_MODEL //裝置型號,整形表示,在ExifInterface中有常量對應表示
  • ExifInterface.TAG_FLASH //閃光燈
  • ExifInterface.TAG_IMAGE_LENGTH //圖片高度
  • ExifInterface.TAG_IMAGE_WIDTH //圖片寬度
  • ExifInterface.TAG_GPS_LATITUDE //緯度
  • ExifInterface.TAG_GPS_LONGITUDE //經度
  • ExifInterface.TAG_GPS_LATITUDE_REF //緯度名(N or S)
  • ExifInterface.TAG_GPS_LONGITUDE_REF //經度名(E or W)
  • ExifInterface.TAG_EXPOSURE_TIME //曝光時間
  • ExifInterface.TAG_APERTURE //光圈值
  • ExifInterface.TAG_ISO //ISO感光度
  • ExifInterface.TAG_DATETIME_DIGITIZED //數字化時間
  • ExifInterface.TAG_SUBSEC_TIME //
  • ExifInterface.TAG_SUBSEC_TIME_ORIG //
  • ExifInterface.TAG_SUBSEC_TIME_DIG //
  • ExifInterface.TAG_GPS_ALTITUDE //海拔高度
  • ExifInterface.TAG_GPS_ALTITUDE_REF //海拔高度
  • ExifInterface.TAG_GPS_TIMESTAMP //時間戳
  • ExifInterface.TAG_GPS_DATESTAMP //日期戳
  • ExifInterface.TAG_WHITE_BALANCE //白平衡
  • ExifInterface.TAG_FOCAL_LENGTH //焦距
  • ExifInterface.TAG_GPS_PROCESSING_METHOD //用於定位查詢的全球定位系統處理方法。

貼出程式碼:

try {
            ExifInterface exifInterface = new ExifInterface(path);
            String dateData = exifInterface.getAttribute(ExifInterface.TAG_DATETIME);
        } catch (IOException e) {
            e.printStackTrace();
        }

建立ExifInterface:
ExifInterface建構函式有三個,接受一個引數

  • String pash
  • FileDescriptor fileDescriptor
  • InputStream inputStream

還有一點需要注意的,saveAttributes()方法主要用於把記憶體中所有當前Exif資訊儲存到目標圖片中,依照官方文件的解釋,它是一個低效率的,它會把圖片的所有Exif資訊,重新依次儲存到目標圖片,所以推薦使用setAttribute()方法進行設定Exif資訊。但是在實際應用中發現,如果僅使用setAttribute()設定Exif資訊,將不會寫入到目標圖片中,只有在改變Exif資訊後,呼叫saveAttribute()才可以把新的Exif寫入到目標圖片中。

寫入資訊

ExifInterface exifInterface = new ExifInterface(filePath);
exifInterface.setAttribute(ExifInterface.TAG_GPS_ALTITUDE,"1/1000");
exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION,"6");
exifInterface.setAttribute(ExifInterface.TAG_IMAGE_WIDTH,"2000");
exifInterface.saveAttributes();

縮圖

getThumbnail()這個方法可以生成一個縮圖,返回一個位元組陣列,得到位元組陣列就可以輕鬆生成Bitmap。

但是在呼叫這個方法前,最好先呼叫exifInterface.hasThumbnail()判斷一下是否有縮圖。

相關文章