Android 下的EXIF

來源:互聯網
上載者:User

標籤:

一.什麼是Exif

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

所有的JPEG檔案以字串“0xFFD8”開頭,並以字串“0xFFD9”結束。檔案頭中有一系列“0xFF??”格式的字串,稱為“標識”,用來 標記JPEG檔案的資訊段。“0xFFD8”表示映像資訊開始,“0xFFD9”表示映像資訊結束,這兩個標識後面沒有資訊,而其它標識緊跟一些資訊字 符。
  0xFFE0 -- 0xFFEF之間的標識符稱為“應用標記”,沒有被常規JPEG檔案利用,Exif正是利用這些資訊串記錄拍攝資訊如快門速度、光圈值等,甚至可以包括全 球定位資訊。按照Exif2.1標準對這些標識符的定義,數位相機可以把各種拍攝資訊記入數位映像中,應用軟體可以讀取這些資料,再按照Exif2.1標 准,檢索出它們的具體含義,一般而言包括以下一些資訊:
  Image Description 映像描述、來源. 指產生映像的工具
  Artist作者 有些相機可以輸入使用者的名字
  Make 生產者 指產品生產廠家
  Model 型號 指裝置型號
  Orientation方向 有的相機支援,有的不支援
  XResolution/YResolution X/Y方向解析度 本欄目已有專門條目解釋此問題。
  ResolutionUnit解析度單位 一般為PPI
  Software軟體 顯示韌體Firmware版本
  DateTime日期和時間
  YCbCrPositioning 色相定位
  ExifOffsetExif資訊位置,定義Exif在資訊在檔案中的寫入,有些軟體不顯示。
  ExposureTime 曝光時間 即快門速度
  FNumber光圈係數
  ExposureProgram曝光程式 指程式式自動曝光的設定,各相機不同,可能是Sutter Priority(快門優先)、Aperture Priority(快門優先)等等。
  ISO speed ratings感光度
  ExifVersionExif版本
  DateTimeOriginal建立時間
  DateTimeDigitized數字化時間
  ComponentsConfiguration映像構造(多指色彩組合方案)
  CompressedBitsPerPixel(BPP)壓縮時每像素色彩位 指壓縮程度
  ExposureBiasValue曝光補償。
  MaxApertureValue最大光圈
  MeteringMode測光方式, 平均式測光、中央重點測光、重點測光等。
  Lightsource光源 指白平衡設定
  Flash是否使用閃光燈。
  FocalLength焦距,一般顯示鏡頭物理焦距,有些軟體可以定義一個係數,從而顯示相當於35mm相機的焦距 MakerNote(User Comment)作者標記、說明、記錄
  FlashPixVersionFlashPix版本 (個別機型支援)
  ColorSpace色域、色彩空間
  ExifImageWidth(Pixel X Dimension)映像寬度 指橫向像素數
  ExifImageLength(Pixel Y Dimension)映像高度 指縱向像素數
  Interoperability IFD通用性擴充項定義指標 和TIFF檔案相關,具體含義不詳
  FileSource源檔案 Compression壓縮比。

二.Camera中拍照流程


在Android Camera程式開發過程中,要用到Exif相關的知識,如果處理不當,會導致拍攝的JPEG圖片無法正常瀏覽。
在Froyo(Android 2.2)源碼中的Camera應用是不對Exif資訊進行寫操作,而只是讀操作,對於Exif的寫操作是交給Camera硬體抽象層去完成,這是 google的設計邏輯。但是不同的Android平台及其相關子平台,再加上不同的Camera應用,相互交替,排列組合,或許會出現這樣一種情況:底 層沒有去寫Exif,而上層應用也沒有寫Exif資訊,那麼圖片的顯示資訊將會丟失。其中影響最為嚴重的是Orientation這個參數。

Froyo camera的邏輯是這樣的:
在Camera這個Activity中,有一個內部類ImageCapture,其中包含一個重要的方法:
private void capture() {
// Set rotation.
mParameters.setRotation(mLastOrientation);
....................
.....................
 mCameraDevice.setParameters(mParameters);

mCameraDevice.takePicture(mShutterCallback, mRawPictureCallback, mPostViewPictureCallback, new JpegPictureCallback(loc));
}

大致流程是這樣的:
1.將拍照時相機的方向添加進Camera.Parameters的執行個體中;
2.將全部相機拍照參數傳給android.hardware.Camera的對象;
3.調用方法takePicture,並設定好非常重要的4個callback;
4.產生Exif資料的事情就由HAL來完成;
5.第4個callback返回資料(這個callback是最重要的,而且是不可預設的,也就是說前3個callback設定成Null也不會影響拍照功能),見如下代碼:
private final class JpegPictureCallback implements PictureCallback {
public void onPictureTaken(final byte[] jpegData, final android.hardware.Camera camera) {
//jpegData為JPEG資料,是由HAL層根據應用傳輸的各種參數(即Camera.Parameters的執行個體)以及JPEG壓縮演算法產生的。
mImageCapture.storeImage(jpegData, camera, mLocation);
}
}

三.Exif使用方法及代碼最佳化方案


什麼地方用到Exif資訊呢?我遇到的至少有如下這麼幾個地方:
1.產生右上方所略圖;
2.圖片顯示應用,例如android內建的gallery3d應用;
3.圖片回顯;
4.短(彩)信等需要添加camera附件的應用.

看看源碼: ImageManager中是這樣讀取Exif方向參數的。
    public static int getExifOrientation(String filepath) {
        int degree = 0;
        ExifInterface exif = null;
        try {
            exif = new ExifInterface(filepath);
        } catch (IOException ex) {
            Log.e(TAG, "cannot read exif", ex);
        }
        if (exif != null) {
            int orientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION, -1);
            if (orientation != -1) {
                // We only recognize a subset of orientation tag values.
                switch(orientation) {
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        degree = 90;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        degree = 180;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        degree = 270;
                        break;
                }

            }
        }
        return degree;
    }

這個方法可以進一步最佳化,從而對於Exif資訊的寫入不再依賴底層。那就是比較一下傳輸給底層的orientation與實際返回的是否相等,不相等就是底層寫入Exif資訊出錯,我們就可以在應用程式層進行修正。
可以添加一個判斷分支如下:(其中EXIF_ORIENTATION是我們緩衝的應用傳給底層的值)。
else if(orientation == 0 && EXIF_ORIENTATION != 0) {
                switch (EXIF_ORIENTATION) {
                case 90:
                    orientation = ExifInterface.ORIENTATION_ROTATE_90;
                    degree = 90;
                    break;
                case 180:
                    orientation = ExifInterface.ORIENTATION_ROTATE_180;
                    degree = 180;
                    break;
                case 270:
                    orientation = ExifInterface.ORIENTATION_ROTATE_270;
                    degree = 270;
                    break;
                }
                exif.setAttribute(ExifInterface.TAG_ORIENTATION, Integer.toString(orientation));
                try {
                    exif.saveAttributes();
                } catch (IOException e) {
                     Log.e(TAG, "cannot save exif", e);
                }
            }


在應用程式層對於Exif的操作是通過android.media.ExifInterface介面完成的。
通過public void setAttribute (String tag, String value) 來設定,而擷取可以通過 public int getAttributeInt (String tag, int defaultValue) 和 public String getAttribute (String tag) 兩種方法都可以,getAttributeInt 重載方法一第二個參數為我們設定的預設值,如果成功則返回相應Tag的值;特定的整數內容為該方法直接傳回值。而重載方法二該方法直接返回結果,如果失敗 則為null。

結論

這樣,經過簡單改造(只是添加了對Exif資訊校正以及寫操作的邏輯)的Camera應用將更加健壯,不依賴平台底層是否處理了Exif資訊,即使出現異常,應用能夠自動修正。
這裡只是以Exif中的 Orientation參數為例,其他參數可以以此類推,保證拍攝出來的圖片符合標準。

 

轉自:http://blog.csdn.net/zoe6553/article/details/6297409

Android 下的EXIF

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.