Camera2 控制图像方向

Camera2 control image orientation

我根据Google camera2示例创建了相机屏幕,所有代码几乎相同,相机拍照并以JPEG格式保存在设备上,但我有一些奇怪的行为。

例如,从模拟器中拍照会将图像旋转90度(图像已旋转,不是预览),在我的华为上图像未旋转。

奇怪的是屏幕旋转和传感器方向值在模拟器和华为 上完全相同。 那么jpeg方向到底是怎么设置的呢?

还在探索CaptureRequest.JPEG_ORIENTATION

captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation))

我注意到此方法对模拟器完全没有影响

保存位图后,我试图从ExifInterface获取JPEG方向,但在Emulator和Huawei中,该值都是ORIENTATION_UNDEFINED。也许在将 Image(从 ImageReader)转换为 File Exif 标签时被忽略?

也许我需要在拍摄图像时手动设置 ExifInterface,但是如果值相同,有什么区别? 我们应该如何控制 JPEG 方向?

使用此方法获取方向(来自 Google camera2 示例)结果对于 Emulator 和 Huawei 是 90 度。

private int getOrientation(int rotation) {
        return (ORIENTATIONS.get(rotation) + mSensorOrientation + 270) % 360;
    }

使用此方法从 ImageReader

获取 Bitmap
public static Bitmap getBitmapFromReader(ImageReader reader) {

    Bitmap bitmap = null;
    Image image = null;

    try {
        image = reader.acquireLatestImage();
        Image.Plane[] planes = image.getPlanes();
        ByteBuffer buffer = planes[0].getBuffer();
        buffer.rewind();
        byte[] data = new byte[buffer.capacity()];
        buffer.get(data);
        bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

    } catch (Exception e) {
        e.printStackTrace();
    }
    if (image != null) {
        image.close();
    }

    return bitmap;
}

模拟器是使用 Camera2 API 的一个非常糟糕的起点。本质上,它具有 LEGACY Camera2 支持,但有一些怪癖。

也就是说,Jpeg 方向在 Android 相机上是一个非常微妙的话题。官方文档解释旋转请求可能适用于图像本身,或仅适用于 EXIF 标志,但某些设备(您测试了哪些华为?)根本不符合。

另请注意 BitmapFactory.decodeByteArray() , since the very beginning.