2012-11-28 6 views
38

Android搭載端末でデバイスカメラを使用して写真を撮ってからサイズを変更すると(アップロードのサイズを小さくするのが非常に一般的です)、このサイズ変更操作がは、のexifメタデータを取り除いていることに気づかないでください。AndroidイメージEXIFデータのサイズ変更と保存(オリエンテーション、ローテーションなど)

この問題は、問題のデバイスがイメージを正しく表示するために 'Orientation'タグに依存している場合に特に問題を引き起こす可能性があります。

さまざまなAndroidデバイスがさまざまな方法でカメラ/画像の回転を処理します.Nexus Oneは常にキャプチャ直後に画像を回転させるように見えるので、ファイルのネイティブコンテンツは常に「直立」です。しかし、他のデバイス(私のテストでは特にサムスンの携帯電話)はではなく、イメージファイルの内容を回転させる - むしろexifのOrientationタグを設定する。画像が後で表示されるときはいつでも、関連する画像コードはオリエンテーション「タグ」の存在を検出し、画像を適切に回転させるべきである。しかし、イメージ上でビットマップ処理を行って新しいファイルに保存した場合、そのexifデータはすべて失われます。 などオリエンテーションデータに加えて、あなたはまた、このようなメイク/モデルとして、他の貴重なメタデータが失われる可能性があります

この

は、携帯電話のギャラリーに表示されたときに画像が直立表示されます(数週間のために私を混同したが、その後に到着します私のサーバーの向きが悪く、明らかなメタデータもない)。他の人を助けるためにここにこの自己質問を追加しています。このブログ記事は非常に有用だった:

http://vikaskanani.wordpress.com/2011/07/17/android-re-size-image-without-loosing-exif-information/

答えて

15

他の人が示されているとおり、あなたは最終的にリサイズされた画像に元の画像からEXIFデータをコピーする必要があります。通常は、Sanselan Androidライブラリがこれに最も適しています。 Android OSのバージョンによっては、ExifInterfaceがEXIFデータを破損することがあります。さらに、ExifInterfaceは限られた数のExifタグも処理します。つまり、「知っている」タグだけです。一方、SanselanはすべてのEXIFタグとマーカーノートを保持します。ここで

は、画像データをコピーするためSanselanを使用する方法を示してブログ記事です: http://bricolsoftconsulting.com/copying-exif-metadata-using-sanselan/

ところで、Android上で私はまた、画像を回転し、オリエンテーションEXIFタグを削除する傾向があります。たとえば、Android 4.03搭載のNexus Sでは、カメラがEXIFメタデータに方向タグを設定していましたが、Webビューはその情報を無視して画像を正しく表示していませんでした。悲しいことに、実際の画像データを回転させてEXIF方向タグを取り除くことは、すべてのプログラムに画像を正しく表示させる唯一の方法です。怠惰なものについては

+0

ありがとうテオ、私はこの答えに感謝し、それを受け入れました。この情報の詳細については、リンクがありますか?「Android OSのバージョンによっては、ExifInterfaceによってEXIFデータが破損することがあります。」 –

+0

これは私の経験に基づいており、ExifInterfaceがバグであることを最初に発見した人ではありません[1]。私が次の日にどれくらいの時間を取っているかによって、いくつかの事例をまとめて報告することができます。 [1] http://mail-archives.apache.org/mod_mbox/commons-issues/201106.mbox/%[email protected]e.org%3E – Theo

+0

@Theo i 'あなたのコードをテストしましたが、一部のデバイスやイメージの属性のほとんどまたはすべてをコピーしているようです。よくコピーされない属性の例は、ISOSpeedRatings、FocalLength、FNumberです。どうやってそれを説明できますか? Android 4.4.2を搭載したnexus 4デバイスでテストし、元のファイルに作成されたExifInterfaceと新しいファイルを比較しました。 –

33

[自己解答]

Afaict、そこに転送バルクであるものは何でも、メタデータを自動的あるいはスナップショットを永続化するメカニズムはありません。

むしろ、ExifInterfaceを使用して特定のプロパティを明示的にチェックし、新しいイメージファイルにコピーする必要があるようです。

http://developer.android.com/reference/android/media/ExifInterface.html

だから、のようなもの:

ExifInterface oldExif = new ExifInterface(oldImagePath); 
String exifOrientation = oldExif.getAttribute(ExifInterface.TAG_ORIENTATION); 

if (exifOrientation != null) { 
    ExifInterface newExif = new ExifInterface(imagePath); 
    newExif.setAttribute(ExifInterface.TAG_ORIENTATION, exifOrientation); 
    newExif.saveAttributes(); 
} 
+0

これは完璧に働きました。ありがとう! – Mauker

22

は、ここでは、再利用可能な機能です:

public static void copyExif(String oldPath, String newPath) throws IOException 
{ 
    ExifInterface oldExif = new ExifInterface(oldPath); 

    String[] attributes = new String[] 
    { 
      ExifInterface.TAG_APERTURE, 
      ExifInterface.TAG_DATETIME, 
      ExifInterface.TAG_DATETIME_DIGITIZED, 
      ExifInterface.TAG_EXPOSURE_TIME, 
      ExifInterface.TAG_FLASH, 
      ExifInterface.TAG_FOCAL_LENGTH, 
      ExifInterface.TAG_GPS_ALTITUDE, 
      ExifInterface.TAG_GPS_ALTITUDE_REF, 
      ExifInterface.TAG_GPS_DATESTAMP, 
      ExifInterface.TAG_GPS_LATITUDE, 
      ExifInterface.TAG_GPS_LATITUDE_REF, 
      ExifInterface.TAG_GPS_LONGITUDE, 
      ExifInterface.TAG_GPS_LONGITUDE_REF, 
      ExifInterface.TAG_GPS_PROCESSING_METHOD, 
      ExifInterface.TAG_GPS_TIMESTAMP, 
      ExifInterface.TAG_IMAGE_LENGTH, 
      ExifInterface.TAG_IMAGE_WIDTH, 
      ExifInterface.TAG_ISO, 
      ExifInterface.TAG_MAKE, 
      ExifInterface.TAG_MODEL, 
      ExifInterface.TAG_ORIENTATION, 
      ExifInterface.TAG_SUBSEC_TIME, 
      ExifInterface.TAG_SUBSEC_TIME_DIG, 
      ExifInterface.TAG_SUBSEC_TIME_ORIG, 
      ExifInterface.TAG_WHITE_BALANCE 
    }; 

    ExifInterface newExif = new ExifInterface(newPath); 
    for (int i = 0; i < attributes.length; i++) 
    { 
     String value = oldExif.getAttribute(attributes[i]); 
     if (value != null) 
      newExif.setAttribute(attributes[i], value); 
    } 
    newExif.saveAttributes(); 
} 
+4

サイズを変更する場合は、TAG_IMAGE_LENGTHとTAG_IMAGE_WIDTHを更新するかコピーしないでください –