Camera2 api拍摄的图片通过ContentResolver获取宽高返回null如何解决
原因分析
- 直接通过
MediaStore.Images.Media.WIDTH和MediaStore.Images.Media.HEIGHT查询返回null,常见于两种场景:- Android 10(API 29)及以上系统,这两个字段已经被标记为deprecated,且如果媒体文件不是由你的应用创建,或者创建时没有主动写入宽高信息,系统不会自动填充这两个值,直接查询会返回null
- 使用Camera2拍摄完成后,你仅写入了文件路径、Bucket相关信息到MediaStore,没有主动将图片的宽高写入对应Media条目
解决方案
你可以根据你的业务场景二选一:
方案1:拍摄完成后主动写入宽高到MediaStore条目
你在Camera2的ImageReader.OnImageAvailableListener回调里拿到Image对象时,本身就可以直接获取到宽高,在插入MediaStore之后直接更新这两个字段即可,后续再查询就能正常拿到值,示例代码:
// 拿到拍摄返回的Image对象 Image image = reader.acquireNextImage(); int width = image.getWidth(); int height = image.getHeight(); // 你之前插入MediaStore得到的contentUri ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.WIDTH, width); values.put(MediaStore.Images.Media.HEIGHT, height); // 执行更新操作 getContentResolver().update(contentUri, values, null, null);
方案2:针对已生成的、无法修改写入逻辑的图片,直接解码图片边界获取宽高
不需要加载整张图片到内存,仅解码边界信息即可拿到宽高,性能开销极低:
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // photoPath为你从DATA字段拿到的文件路径 BitmapFactory.decodeFile(photoPath, options); int width = options.outWidth; int height = options.outHeight;
如果仅拿到了图片的contentUri,可以通过输入流读取:
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; try (InputStream is = getContentResolver().openInputStream(contentUri)) { BitmapFactory.decodeStream(is, null, options); int width = options.outWidth; int height = options.outHeight; } catch (IOException e) { e.printStackTrace(); }
注意:API 29以上如果访问其他应用生成的媒体文件,需要申请
READ_EXTERNAL_STORAGE权限,仅访问你自己应用生成的媒体不需要额外权限。
内容的提问来源于stack exchange,提问作者Richa
相关产品推荐
相关产品推荐

