相机来源(Google Mobile Vision)会在某些设备上返回旋转的图像

时间:2018-01-29 13:09:45

标签: android android-camera camera-calibration google-vision

我有Google Mobile Vision的开源代码 - CameraSource,这是我调用点击照片的方法:cameraSource.takePicture();

在开源版本的CameraSource.java中,确定屏幕方向的方法是库存方法:

private void setRotation(Camera camera, Camera.Parameters parameters, int cameraId) {
        WindowManager windowManager =
                (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        int degrees = 0;
        int rotation = windowManager.getDefaultDisplay().getRotation();
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
            default:
                Log.e(TAG, "Bad rotation value: " + rotation);
        }

        CameraInfo cameraInfo = new CameraInfo();
        Camera.getCameraInfo(cameraId, cameraInfo);

        int angle;
        int displayAngle;
        if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
            angle = (cameraInfo.orientation + degrees) % 360;
            displayAngle = (360 - angle) % 360; // compensate for it being mirrored
        } else {  // back-facing
            angle = (cameraInfo.orientation - degrees + 360) % 360;
            displayAngle = angle;
        }

        // This corresponds to the rotation constants in {@link Frame}.
        mRotation = angle / 90;

        camera.setDisplayOrientation(displayAngle);
        parameters.setRotation(angle);
    }

此处,三星,联想和Yuntab H8的displayAngle和角度相同。但是为backCamera返回的位图在每个设备中的旋转方式都不同。我必须手动旋转每个设备的位图(三星:90,联想:0和Yuntab:180)

我的要求是onPictureTaken应该返回一个与当前显示方向匹配的位图。我正在研究这个问题,因为很长一段时间但仍需要找到解决方案的方法。下面是我的onPicturetaken()(拍照后调用):

  @Override
        public void onPictureTaken(byte[] bytes) {
            try {
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 2;
                bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, currentCameraId == 0 ? options : null);
            }catch (Exception ex){
                ex.printStackTrace();
                Log.e("PictureTaken",ex.toString());
        }
    };

1 个答案:

答案 0 :(得分:2)

当图像已保存在设备中时,您应旋转图像。

然后你可以旋转它以匹配照片拍摄时的位置。

示例代码(可能需要一些清理和改进,但它可以运行 ...):

方法确实计算图像的旋转:

private static int rotationNeeded(String path) {
    try {
        File file = new File(path);

        if (!file.getName().contains(".jpg")) {
            return 0;
        }

        ExifInterface exif = new ExifInterface(file.getAbsolutePath());
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

        if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
            return 270;
        }

        if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
            return 180;
        }

        if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
            return 90;
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return 0;
}

应用图片所需的旋转:

public static void rotateImage(String filePath) {
    try {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 2;
        Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);

        //check image rotation
        int rotate = rotationNeeded(filePath);
        if (rotate != 0) {
            //rotate image if needed
            Matrix matrix = new Matrix();
            matrix.postRotate(rotate);
            Bitmap rotatedImage = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                    bitmap.getHeight(), matrix, true);

            bitmap.recycle();
            bitmap = rotatedImage;

            //save image
            byte[] dataPicture = bao.toByteArray();
            FileOutputStream fos = new FileOutputStream(filePath);
            fos.write(dataPicture);
            fos.flush();
            fos.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}