web-dev-qa-db-ja.com

ギャラリー/カメラの意図からの画像の向き

カメラ/ギャラリーインテントからアプリに画像を取得しています。多くの携帯電話で、私が意図から読み取った画像/ Uriはすでに正しい向きに回転しています。たとえば、N1、Legend、Desireなどです。

しかし、一部の電話(Milestone1、GalaxySなど)では、写真がどのように撮られたとしても、写真は常に横長になります。これは、私のアプリケーションでは、ポートレート画像がユーザーに間違った方法で表示されることを意味します。画像のEXIF情報を読み込もうとしましたが、方向タグは常に0です。Milestone1では、ギャラリーアプリケーションがポートレート画像を正しく表示するため、画像の正しい方向を見つける方法が必要です。

ユーザーに表示する前に自分で画像を回転する必要があるかどうかを確認するにはどうすればよいですか?

助けてくれてありがとう!

32
Juhani

ギャラリーの画像には、Florian Answerが機能しています。

次のコードはキャプチャされた画像で機能しますが、ギャラリー画像では試していませんが、機能するはずです。これが誰にも役立つことを願っています。

コード:

public static int getCameraPhotoOrientation(Context context, Uri imageUri, String imagePath){
     int rotate = 0;
     try {
         context.getContentResolver().notifyChange(imageUri, null);
         File imageFile = new File(imagePath);
         ExifInterface exif = new ExifInterface(
                 imageFile.getAbsolutePath());
         int orientation = exif.getAttributeInt(
                 ExifInterface.TAG_ORIENTATION,
                 ExifInterface.ORIENTATION_NORMAL);

         switch (orientation) {
         case ExifInterface.ORIENTATION_ROTATE_270:
             rotate = 270;
             break;
         case ExifInterface.ORIENTATION_ROTATE_180:
             rotate = 180;
             break;
         case ExifInterface.ORIENTATION_ROTATE_90:
             rotate = 90;
             break;
         }


         Log.v(TAG, "Exif orientation: " + orientation);
     } catch (Exception e) {
         e.printStackTrace();
     }
    return rotate;
 }

編集:コメントで読み取れるように、一部のデバイスはExif情報をサポートしていません。チェックされていませんが、HTCではサポートされていません。必ずデバイスを確認し、代替デバイスを作成してください。

25
eric.itzhak

次のメソッドは、画像の向きを度数で返します。ギャラリーからの画像で動作します。の戻り値:

  • 通常の風景:0
  • 通常のポートレート:90
  • 逆さの風景:180
  • 逆さのポートレート:270
  • 画像が見つかりません:-1

コード:

public static int getOrientation(Context context, Uri photoUri) {
    Cursor cursor = context.getContentResolver().query(photoUri,
            new String[] { MediaStore.Images.ImageColumns.ORIENTATION },
            null, null, null);

    try {
        if (cursor.moveToFirst()) {
            return cursor.getInt(0);
        } else {
            return -1;
        }
    } finally {
        cursor.close();
    }
}
16
        int rotate = 0;
        try {
            File imageFile = new File(sourcepath);
            ExifInterface exif = new ExifInterface(
                    imageFile.getAbsolutePath());
            int orientation = exif.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);

            switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                rotate = 270;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                rotate = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                rotate = 90;
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Matrix matrix = new Matrix();
        matrix.postRotate(rotate);
        bitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
3
vineet pal

これは、私が見つけた最良の答えです。 https://stackoverflow.com/a/20480741/2258389
ギャラリーやカメラに最適

2
Jason

S1にも同じ問題があります。ストックギャラリーアプリを使用して画像を開いても、横向きモードで開くことに気付きました(携帯電話は写真の正しい向きを認識していません)。
また、カメラアプリで電話を縦向きに回転させた場合、アイコン(写真、フォーカス、設定)は回転しません。S2または任意のデバイスで横向き/縦向きカメラをサポートしている場合は、アイコンが回転します。

ストックカメラアプリが比例配分モードでの写真の撮影をサポートしていないと確信しています。

1
JafarKhQ
Matrix matrix = new Matrix();

ExifInterface exifReader = new ExifInterface(filePath);

int orientation = exifReader.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);

if (orientation ==ExifInterface.ORIENTATION_NORMAL) {

      // Do nothing. The original image is fine.

} else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {

       matrix.postRotate(90);

} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {

       matrix.postRotate(180);

} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {

      matrix.postRotate(270);

}
1
Anh Duy

最初にcontentresolverを使用してギャラリーオブジェクトを作成してから、作成したURIを画像キャプチャインテントに渡す必要があります。次に、ギャラリーの方向データではなく、exifデータを確認できます。

1
Eric Novins

これは、この質問で解決された同じ問題のようです: Android:ギャラリーからロードされたビットマップはImageViewで回転されます

0
Loktar

私は同じ問題を抱えていたので、私はすでにプロジェクトのためにそれをしました(Androidはあなたが風景で写真を撮るだけだと思っています)。私が行ったのは、その時の電話の向きを検出してから、画像を回転させることでした。ただし、インテントを受け取ったときの向きは同じであると想定しています。

0
Valentin Rocher

このように使用してください!

private static int exifToDegrees(int exifOrientation) {
    if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
        return 90;
    } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
        return 180;
    } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
        return 270;
    }
    return 0;
}

そしてコードでは、

Bitmap newImage = Bitmap.createBitmap(actualImage, 0, 0, width, height, matrix, true);

シンプル!

0
nithinreddy

私がやっていること:まず、メタデータ情報を使用してカメラで撮影した画像の向きを確認します。これが縦向きで見つかった場合は、画像を90度回転し、それ以外の場合は表示のみを行う必要があります。

画像の向きに関する情報を取得するには、Exifインターフェースを使用できます。それでおしまい!

0
g4gaj

単純なexiftodegreeの回答は、写真を撮ったときにのみ機能し、私はそれをそのために使用します。写真の選択と正しい向きの取得で問題が発生した場合は、こちらの私の回答を参照してください: 画像の向き-Android

0
A.Sanchez.SD