Android - 摄像头在某些设备的后置摄像头上提供颠倒的数据

Android - Camera provide upside down data on back camera in some devices

我在 GLSurfaceView 上渲染 camera preview 一切正常,但 camera preview 在某些设备上显示颠倒,特别是在 Nexus 5X 上。我已经检查了这个解决方案 Android - Camera preview is sideways .这是我处理方向问题的代码

 private void setCameraDisplayOrientation() {
    Constants.debugLog(TAG_DEBUG, "setCameraDisplayOrientation");
    Constants.debugLog(TAG, "setCameraDisplayOrientation ");

    if (camera == null) {
        Constants.debugLog(TAG + " Owncamera", "setCameraDisplayOrientation - camera null");
        return;
    }

    Camera.CameraInfo info = new Camera.CameraInfo();
    Camera.getCameraInfo(currentCameraId, info);

    WindowManager winManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    int rotation = winManager.getDefaultDisplay().getRotation();

    int degrees = 0;

    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;
    }

    int result;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        result = (info.orientation + degrees) % 360;
        result = (360 - result) % 360;  // compensate the mirror
    } else {  // back-facing
        result = (info.orientation - degrees + 360) % 360;
    }

    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        this.cameraOrientation = 2;
    } else if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
        this.cameraOrientation = 1;
    }

    Constants.debugLog(TAG_DEBUG, "result: " + result + "  this.cameraOrientation == " + this.cameraOrientation);
    Constants.debugLog(TAG, "result: " + result + "  this.cameraOrientation == " + this.cameraOrientation);
    //Log.e("camera_orient", "res: "+ result);
    camera.setDisplayOrientation(result);
}

Camera.CameraInfo info class,我可以得到 orientation 。对于最大设备,我在 portrait mode 上获得的值是“for front camera = 270, back camera = 90”,但在 Nexus 5X 上它为两个前端提供 camera orientation 270,270 &后置摄像头。除了在其他设备上,我的相机在纵向模式下为前后摄像头提供 result 值 90,但对于 Nexus 5x 前置摄像头 90 后置摄像头 270。我也尝试通过设置值固定 90在 camera.setDisplayOrientation(90); Nexus 5X 设备上但不工作 如何处理这个问题,以便所有设备相机的方向都相同,我不会得到任何旋转的图像??

尝试

1.首先,添加下面定义的方法(writeFile、processImage和getCorrectCameraOrientation)

2. 拍摄照片后计算相机方向并更新 onPictureTaken**

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

    int rotationAngle = getCorrectCameraOrientation (this, info);

3. 创建文件并使用 rotationAngle 更新照片角度

File file = new File (folder, fileName);

try {
    file.createNewFile ();
}
catch (IOException e) {
    e.printStackTrace ();
}

writeFile (data, file);
processImage (file, rotationAngle, compressRatio);

writeFile

public static void writeFile (byte[] data, File file) throws IOException {

    BufferedOutputStream bos = null;

    try {
        FileOutputStream fos = new FileOutputStream (file);
        bos = new BufferedOutputStream (fos);
        bos.write (data);
    }
    finally {
        if (bos != null) {
            try {
                bos.flush ();
                bos.close ();
            }
            catch (Exception e) {
            }
        }
    }
}

processImage

public static void processImage (File file, int rotationAngle, int compressionRatio) {

    BufferedOutputStream bos = null;

    try {

        Bitmap bmp = BitmapFactory.decodeFile (file.getPath ());

        Matrix matrix = new Matrix ();
        matrix.postRotate (rotationAngle);

        bmp = Bitmap.createBitmap (bmp, 0, 0, bmp.getWidth (), bmp.getHeight (), matrix, true);

        FileOutputStream fos = new FileOutputStream (file);
        bmp.compress (Bitmap.CompressFormat.PNG, compressionRatio, fos);
    }
    catch (IOException e) {
        e.printStackTrace ();
    }
    catch (OutOfMemoryError t) {
        t.printStackTrace ();
    }
    catch (Throwable t) {
        t.printStackTrace ();
    }
    finally {
        if (bos != null) {
            try {
                bos.flush ();
                bos.close ();
            }
            catch (Exception e) {
            }
        }
    }
}

getCorrectCameraOrientation

    public static int getCorrectCameraOrientation (Activity activity, Camera.CameraInfo info) {

    int rotation = activity.getWindowManager ().getDefaultDisplay ().getRotation ();
    int degrees = 0;

    if (hasValidRotation (rotation)) {
        degrees = rotation * 90;
    }

    int result;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        result = (info.orientation + degrees) % 360;
        result = (360 - result) % 360;
    }
    else {
        result = (info.orientation - degrees + 360) % 360;
    }

    return result;
}

问题原因: 默认最大设备数 return 使用相机时默认方向为 90 度的图像 api 1. 我不确定这是在使用相机 api 2 的情况下。但是在 Nexus 5x 和一些稀有设备(使用相机 api 1)的情况下,它 return 默认旋转 270 度的图像是一个例外某些特定型号设备上的情况。所以你必须为 Nexus 5X 添加 180 度的附加旋转。请查看打印 Nexus 5X 图像方向的日志。