【问题标题】:Reliable method for getting properly rotated bitmap from camera/gallery从相机/图库中获取正确旋转位图的可靠方法
【发布时间】:2016-06-28 03:10:08
【问题描述】:

这是困扰我几个月的问题。我看过所有关于旋转从图库中选择或通过图像捕获意图拍摄的图像的 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 和其他不起作用的垃圾。有人可以告诉我使用所有本机意图获得正确图像旋转的确切方法,以便正确显示所有图像吗?提前致谢。

【问题讨论】:

    标签: android image android-intent bitmap rotation


    【解决方案1】:

    不确定从图库中选择的照片,但对于直接从相机拍摄的照片,您可以试试这个:

    在要捕获照片的活动/片段中,尝试在 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...
                }
            }
    

    希望这会有所帮助。

    【讨论】:

    • 谢谢,但我不是手动管理相机,而是使用 3rd 方应用程序来捕捉/选择图像。
    • 当我尝试从 Exif 获取方向数据时,我确实遇到了这种情况。不幸的是,我没有找到解决方案。
    猜你喜欢
    • 2019-05-30
    • 2011-11-09
    • 2014-10-24
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多