Android 如何找到使用 Intent MediaStore.ACTION_IMAGE_CAPTURE 拍摄的图片的方向?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2284851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:16:42  来源:igfitidea点击:

How can I find the orientation of a picture taken with Intent MediaStore.ACTION_IMAGE_CAPTURE?

androidcameraandroid-intent

提问by Arcantos

When I take a picture with Android's camera app, it detects the phone's orientation and saves the picture accordingly. So if I take a picture of a building, the roof will be on the topside, whether I hold the phone in landscape position or portrait.

当我使用 Android 的相机应用拍照时,它会检测手机的方向并相应地保存图片。因此,如果我拍摄建筑物的照片,无论我将手机横放还是竖放,屋顶都将位于顶部。

However, when I use

但是,当我使用

Intent imageCaptureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

to get a picture, the camera app doesn't react to the orientation. If I hold the phone vertically (portrait), the resulting picture will be rotated, with said building's roof to the left of the screen.

要获取照片,相机应用程序不会对方向做出反应。如果我垂直握住手机(纵向),则生成的图片将旋转,所述建筑物的屋顶位于屏幕左侧。

How can I set the intent so that the camera will take the orientation into account?

如何设置意图以便相机将方向考虑在内?

Or can I deduce in some way in what orientation the picture was taken and rotate it myself afterwards?

或者我可以以某种方式推断出照片的拍摄方向并在之后自己旋转吗?

Or is there another way?

或者还有其他方法吗?

回答by Arcantos

I found the answer. The Exifof the image has an indicator of the orientation. Just in case, Exif can be viewed in Android like this:

我找到了答案。图像的Exif具有方向指示符。以防万一,可以像这样在 Android 中查看 Exif:

ExifInterface exif = new ExifInterface("filepath");  
exif.getAttribute(ExifInterface.TAG_ORIENTATION);

回答by user2832184

Read from Exif if available, otherwise read from MediaStore

如果可用,从 Exif 读取,否则从 MediaStore 读取

public static int getImageOrientation(Context context, String imagePath) {
    int orientation = getOrientationFromExif(imagePath);
    if(orientation <= 0) {
        orientation = getOrientationFromMediaStore(context, imagePath);
    }

    return orientation;
}

private static int getOrientationFromExif(String imagePath) {
    int orientation = -1;
    try {
        ExifInterface exif = new ExifInterface(imagePath);
        int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 
                ExifInterface.ORIENTATION_NORMAL);

        switch (exifOrientation) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                orientation = 270;

                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                orientation = 180;

                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                orientation = 90;

                break;

            case ExifInterface.ORIENTATION_NORMAL:
                orientation = 0;

                break;
            default:
                break;
        }
    } catch (IOException e) {
        Log.e(LOG_TAG, "Unable to get image exif orientation", e);
    }

    return orientation;
}

private static int getOrientationFromMediaStore(Context context, String imagePath) {
    Uri imageUri = getImageContentUri(context, imagePath);
    if(imageUri == null) {
        return -1;
    }

    String[] projection = {MediaStore.Images.ImageColumns.ORIENTATION};
    Cursor cursor = context.getContentResolver().query(imageUri, projection, null, null, null);

    int orientation = -1;
    if (cursor != null && cursor.moveToFirst()) {
        orientation = cursor.getInt(0);
        cursor.close();
    }

    return orientation;
}

private static Uri getImageContentUri(Context context, String imagePath) {
    String[] projection = new String[] {MediaStore.Images.Media._ID};
    String selection = MediaStore.Images.Media.DATA + "=? ";
    String[] selectionArgs = new String[] {imagePath};
    Cursor cursor = context.getContentResolver().query(IMAGE_PROVIDER_URI, projection, 
            selection, selectionArgs, null);

    if (cursor != null && cursor.moveToFirst()) {
        int imageId = cursor.getInt(0);
        cursor.close();

        return Uri.withAppendedPath(IMAGE_PROVIDER_URI, Integer.toString(imageId));
    } 

    if (new File(imagePath).exists()) {
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.DATA, imagePath);

        return context.getContentResolver().insert(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    } 

    return null;
}

回答by savepopulation

For a quick fix, you can check if the image's width is bigger than the image's height. It means it's landscape and you can change it to portrait.

为了快速修复,您可以检查图像的宽度是否大于图像的高度。这意味着它是横向的,您可以将其更改为纵向。

private Bitmap fromGallery(final Uri selectedImageUri) {
    try {
        Bitmap bm = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);

        ExifInterface exif = new ExifInterface(selectedImageUri.getPath());
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

        int angle = 0;
        switch (orientation) {

            case ExifInterface.ORIENTATION_ROTATE_90:
                angle = 90;
                break;

            case ExifInterface.ORIENTATION_ROTATE_180:
                angle = 180;
                break;

            case ExifInterface.ORIENTATION_ROTATE_270:
                angle = 270;
                break;

            default:
                angle = 0;
                break;
        }

        Matrix mat = new Matrix();

        if (angle == 0 && bm.getWidth() > bm.getHeight())
            mat.postRotate(90);
        else
            mat.postRotate(angle);

        return Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), mat, true);

    }
    catch (IOException e) {
        Log.e("", "-- Error in setting image");
    }
    catch (OutOfMemoryError oom) {
        Log.e("", "-- OOM Error in setting image");
    }
    return null;
}

回答by Ricardo Saracino

I used a file provider and nothing worked except making a temporary copy and reading the data from it.

我使用了一个文件提供程序,除了制作临时副本并从中读取数据外,没有任何效果。

public static int getOrientation(Context context, Uri uri) {

    int rotate = 0;

    try {

        ParcelFileDescriptor parcelFileDescriptor =
                context.getContentResolver().openFileDescriptor(uri, "r");

        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();

        FileInputStream input = new FileInputStream(fileDescriptor);

        File tempFile = File.createTempFile("exif", "tmp");

        String tempFilename = tempFile.getPath();

        FileOutputStream output = new FileOutputStream(tempFile.getPath());

        int read;

        byte[] bytes = new byte[4096];

        while ((read = input.read(bytes)) != -1) {
            output.write(bytes, 0, read);
        }

        input.close();
        output.close();

        ExifInterface exif = new ExifInterface(tempFile.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) {
        Log.i(TAG, e.getLocalizedMessage());
    }

    return rotate;
}

bonus rotate function

奖金轮换功能

public static Bitmap rotateImage(Context context, Uri uri, int orientation) throws IOException {

    ParcelFileDescriptor parcelFileDescriptor =
            context.getContentResolver().openFileDescriptor(uri, "r");
    FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
    Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
    parcelFileDescriptor.close();

    if (orientation > 0) {
        Matrix matrix = new Matrix();
        matrix.postRotate(orientation);

        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    }

    return bitmap;
}