从相机/图库中获取正确旋转位图的可靠方法

时间:2016-06-28 03:10:09

标签: android image android-intent bitmap rotation

这个问题困扰着我的MONTHS。我已经看到所有 SO帖子有关于旋转从图库中选择的图像或通过图像捕获意图拍摄的图像,但没有一个有效。当然,大罪犯是三星设备,但我甚至在Nexus上看到了一些时髦的行为。

我使用意图从图库和相机中选择图像,但似乎风景照片总是似乎旋转90度。第一步始终是ExifInterface,如下所示:

ExifInterface exif = new ExifInterface(imageUri.getLastPathSegment();
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationNeeded = getRotationFromExifData(orientation);
Matrix matrix = new Matrix();
matrix.setRotate(rotationNeeded);

其中getRotationFromExifData(orientation)是:

private static int getRotationFromExifData(int orientation) {
    Log.d(LOG_TAG, "Orientation: " + orientation);
    switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            Log.d(LOG_TAG, "Exif returned 90");
            return 90;
        case ExifInterface.ORIENTATION_ROTATE_180:
            Log.d(LOG_TAG, "Exif returned 180");
            return 180;
        case ExifInterface.ORIENTATION_ROTATE_270:
            Log.d(LOG_TAG, "Exif returned 270");
            return 270;
        default: // Normal or 0
            Log.d(LOG_TAG, "Exif returned 0");
            return 0;
    }
}

这不起作用,ExifInterface(从我看到的)总是返回0(或正常),特别是在三星设备上。

其他步骤包括查询MediaStore和其他无效的垃圾。有人可以告诉我使用所有原生意图获得正确图像旋转的确切方法,所以所有图像都正确显示?提前谢谢。

1 个答案:

答案 0 :(得分:0)

不确定从相册中选择的照片,但直接从相机拍摄的照片,您可以尝试:

在您的活动/片段中捕获照片,尝试在onResume()中添加并启用OrientationEventListener,并在onPause()中禁用它。

这是onResume()

@Override
public void onResume() {
    super.onResume();
    orientationListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
            @Override
            public void onOrientationChanged(int angle) {
                if (angle > 315 || angle <= 45) {
                    rotation = 90;
                } else if (angle > 45 && angle <= 135) {
                    rotation = 180;
                } else if (angle > 135 && angle <= 225) {
                    rotation = 270;
                } else if (angle > 225 && angle <= 315) {
                    rotation = 0;
                } else {
                    rotation = -1;// UNKNOWN
                }

                if (currentFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                    rotation = (360 - rotation) % 360;
                }

                Log.i("Orientation", "rotation = " + rotation);
            }
        };

        if (orientationListener.canDetectOrientation()) {
            orientationListener.enable();
        }
}

这是onPause()

@Override
public void onPause() {
    //...
    orientationListener.disable();
    super.onPause();
}

使用相机拍摄照片时,请使用该旋转相应地旋转位图,如下所示:

       camera.takePicture(null, null, null, new PictureCallback() {

            @Override
            public void onPictureTaken(byte[] data, Camera camera) {

                Bitmap theBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

                if (rotation != -1) {
                    Matrix matrix = new Matrix();
                    matrix.postRotate(rotation);

                    theBitmap = Bitmap.createBitmap(theBitmap, 0, 0, theBitmap.getWidth(), theBitmap.getHeight(), matrix, false);
                }

                // Save the bitmap here...
            }
        }

希望这有帮助。