You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Pixel2 XL安卓8.1.0下Camera API拍摄照片Exif分辨率异常问题

解决Google Pixel 2 XL(Android 8.1.0)Camera API竖拍照片Exif分辨率错误问题

我之前碰到过不少开发者在Pixel 2 XL(Android 8.1.0)上遇到这个Camera API的坑——竖屏拍的照片Exif分辨率显示不对,横屏却正常。先给你拆解下问题根源,再给几个靠谱的解决办法:

问题到底出在哪?

这个问题的核心是Camera API在竖屏拍摄时,Exif的分辨率字段和方向标签不匹配。Pixel 2 XL的传感器本身是横屏的,竖屏拍摄时,Camera API会给照片加上Orientation(方向)Exif标签(比如顺时针转90度的标签值是6),告诉后续的应用“这张图要旋转90度看”,但却没同步更新ImageWidthImageLength这两个分辨率字段——这俩字段依然写的是传感器原生的横屏宽高。

而大多数文件管理器查看照片属性时,只会直接读ImageWidthImageLength,忽略了方向标签,所以就出现了“明明是竖屏照片,属性却显示横屏分辨率”的错觉。横屏拍摄时传感器方向和屏幕一致,所以分辨率字段和实际显示匹配,就没这个问题。

怎么解决?

1. 拍完照后手动修正Exif分辨率

用Android自带的ExifInterface类,根据方向标签来交换宽高值,让分辨率字段和实际显示的尺寸对应。示例代码如下:

// 传入照片文件路径
ExifInterface exif = new ExifInterface(photoFilePath);
// 获取照片的方向标签
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

int originalWidth = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
int originalHeight = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);

// 如果是顺时针/逆时针旋转90度的情况,交换宽高
if (orientation == ExifInterface.ORIENTATION_ROTATE_90 || orientation == ExifInterface.ORIENTATION_ROTATE_270) {
    exif.setAttribute(ExifInterface.TAG_IMAGE_WIDTH, String.valueOf(originalHeight));
    exif.setAttribute(ExifInterface.TAG_IMAGE_LENGTH, String.valueOf(originalWidth));
    // 保存修改后的Exif信息
    exif.saveAttributes();
}

2. 拍摄前就选对适配方向的拍照尺寸

初始化Camera的时候,根据当前屏幕方向,从支持的拍照尺寸里选对应方向的尺寸——竖屏选高大于宽的,横屏选宽大于高的。这样拍完的照片,分辨率字段本身就和显示方向匹配,不用事后修正。示例代码:

Camera camera = Camera.open();
Camera.Parameters params = camera.getParameters();
List<Camera.Size> supportedSizes = params.getSupportedPictureSizes();

// 获取当前屏幕方向
int screenOrientation = getResources().getConfiguration().orientation;
Camera.Size targetSize = null;

if (screenOrientation == Configuration.ORIENTATION_PORTRAIT) {
    // 竖屏:挑高度最大且高度>宽度的尺寸
    for (Camera.Size size : supportedSizes) {
        if (size.height > size.width) {
            if (targetSize == null || size.height > targetSize.height) {
                targetSize = size;
            }
        }
    }
} else {
    // 横屏:挑宽度最大且宽度>高度的尺寸
    for (Camera.Size size : supportedSizes) {
        if (size.width > size.height) {
            if (targetSize == null || size.width > targetSize.width) {
                targetSize = size;
            }
        }
    }
}

// 设置选中的拍照尺寸
if (targetSize != null) {
    params.setPictureSize(targetSize.width, targetSize.height);
    camera.setParameters(params);
}

3. 极端情况:直接旋转图片像素(不推荐)

如果碰到完全不支持Exif方向标签的文件管理器,也可以在拍照后直接把图片像素旋转到正确方向,生成一张新图。但这种方式会额外占用存储空间,而且会损失一点画质,除非必要不建议用。

验证方法

按照你给出的复现步骤重新测试:

  • 竖屏拍摄后应用上述任一方案,再打开文件管理器看属性,分辨率应该和实际竖屏尺寸一致;
  • 横屏拍摄的照片依然保持正常显示。

内容的提问来源于stack exchange,提问作者Vivek Gabadiya

火山引擎 最新活动