You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Camera2 API图像旋转异常:Nokia 6.1竖拍照片显示为横屏

解决Nokia 6.1上Camera2 API竖拍照片显示横屏的问题

我之前处理过类似Android One设备的Camera2 API方向适配问题,结合你描述的情况——已经尝试了两种标准的JPEG_ORIENTATION计算方法,返回值都是90但在Nokia 6.1上完全无效,其他设备正常——大概率是这款设备的Camera Provider实现对CaptureRequest.JPEG_ORIENTATION参数的处理有特殊逻辑,或者EXIF元数据的写入/解析存在差异。下面给你几个针对性的解决方案:

先排查核心原因:确认传感器方向和EXIF数据

在动手调整代码前,先做两个小检查,帮你定位问题:

  • 打印传感器方向:Nokia 6.1的相机传感器方向可能和你预期的不同,比如不是常见的90或270。在获取CameraCharacteristics时加一行日志:
    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    String cameraId = "你的相机ID"; // 比如后置相机ID
    CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
    int sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
    Log.d("CamDebug", "Nokia 6.1 Sensor Orientation: " + sensorOrientation);
    
    如果这个值不是90,那你之前的方向计算逻辑就需要调整。
  • 检查EXIF信息:用文件管理器查看拍摄后的JPEG照片的EXIF属性,看Orientation字段是否是90。如果这个字段是0或者其他值,说明相机根本没把你设置的JPEG_ORIENTATION写入EXIF,这就是ImageView显示横屏的原因。

解决方案1:手动读取EXIF并旋转Bitmap显示

既然相机可能没正确写入EXIF,或者ImageView没正确解析,咱们就手动处理:

// 工具方法:根据EXIF旋转Bitmap
public static Bitmap getRotatedBitmapFromPath(String photoPath) {
    Bitmap rawBitmap = BitmapFactory.decodeFile(photoPath);
    if (rawBitmap == null) return null;

    ExifInterface exif;
    try {
        exif = new ExifInterface(photoPath);
    } catch (IOException e) {
        e.printStackTrace();
        return rawBitmap;
    }

    int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
    Matrix matrix = new Matrix();
    switch (exifOrientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            matrix.postRotate(90);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            matrix.postRotate(180);
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            matrix.postRotate(270);
            break;
        default:
            return rawBitmap;
    }

    return Bitmap.createBitmap(rawBitmap, 0, 0, rawBitmap.getWidth(), rawBitmap.getHeight(), matrix, true);
}

然后在ImageView中使用这个方法:

ImageView photoView = findViewById(R.id.your_image_view);
Bitmap rotatedBitmap = getRotatedBitmapFromPath("你的照片路径");
if (rotatedBitmap != null) {
    photoView.setImageBitmap(rotatedBitmap);
}

解决方案2:强制同时设置JPEG_ORIENTATION和EXIF参数

有些Android One设备需要显式设置EXIF方向参数,即使文档说JPEG_ORIENTATION会自动控制它。试试在构建CaptureRequest.Builder时添加一行:

int calculatedOrientation = 你的计算结果; // 比如90
captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, calculatedOrientation);
// 额外添加这一行,强制写入EXIF方向
captureRequestBuilder.set(CaptureRequest.JPEG_EXIF_ORIENTATION, calculatedOrientation);

这样能确保相机硬件同时处理JPEG旋转和EXIF元数据写入。

解决方案3:手动旋转图像数据(如果前面方法都无效)

如果Nokia 6.1的相机完全忽略了方向参数,那咱们直接在图像输出环节手动旋转:
用ImageReader获取原始JPEG数据,解码成Bitmap后旋转再保存:

// 初始化ImageReader时注意尺寸(竖屏时可能需要交换宽高?)
ImageReader imageReader = ImageReader.newInstance(竖屏宽度, 竖屏高度, ImageFormat.JPEG, 1);
imageReader.setOnImageAvailableListener(reader -> {
    Image image = reader.acquireNextImage();
    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
    byte[] jpegData = new byte[buffer.remaining()];
    buffer.get(jpegData);

    // 解码并旋转
    Bitmap rawBitmap = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length);
    Matrix rotateMatrix = new Matrix();
    rotateMatrix.postRotate(90); // 根据你的需要设置旋转角度
    Bitmap rotatedBitmap = Bitmap.createBitmap(rawBitmap, 0, 0, rawBitmap.getWidth(), rawBitmap.getHeight(), rotateMatrix, true);

    // 保存旋转后的图像
    try (FileOutputStream fos = new FileOutputStream("你的输出文件路径")) {
        rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
    } catch (IOException e) {
        e.printStackTrace();
    }

    image.close();
}, null);

这种方法虽然麻烦,但能彻底绕开设备的Camera2 API适配问题。

总结

Nokia 6.1作为Android One设备,厂商对Camera2 API的实现可能更贴近原生但有特殊处理,优先尝试解决方案1(手动处理EXIF旋转),这是最通用的适配方式;如果还是不行,再试试显式设置EXIF参数或者手动旋转图像数据。

内容的提问来源于stack exchange,提问作者Manuj Jagga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:34:57