23. 相机分辨率与比例:Sensor分辨率、预览分辨率、图片分辨率、比例选择策略
说到Android摄像头开发,分辨率这块儿,我敢说十个新手有九个会栽跟头。我自己刚入行那会儿,也在这上面吃过不少亏。今天咱们就把这事儿彻底捋清楚。
23.1 三个分辨率,各司其职
先搞清楚三个概念:Sensor分辨率、预览分辨率、图片分辨率。它们不是一回事,千万别混为一谈。
| 分辨率类型 | 作用 | 典型值 |
|---|---|---|
| Sensor分辨率 | 摄像头硬件能输出的最大分辨率 | 4000×3000 (12MP) |
| 预览分辨率 | 取景器显示的画面大小 | 1920×1080 (1080p) |
| 图片分辨率 | 最终拍出的照片大小 | 4000×3000 (12MP) |
Sensor分辨率是硬件的天花板。你没法超过它。预览和图片分辨率,都是从Sensor输出里裁切或缩放得到的。
核心原则:预览分辨率 ≠ 图片分辨率。它们可以不同,而且很多时候,不同才是对的。
23.2 比例之争:4:3、16:9、1:1
比例这事儿,说白了就是画面长宽比。常见的就三种:
- 4:3 —— 最传统,Sensor原生比例。能用到Sensor的全部像素。
- 16:9 —— 宽屏,适合视频和横屏场景。但注意,它是在4:3基础上裁切上下部分得到的。
- 1:1 —— 正方形,社交分享常用。同样是在4:3基础上裁切。
我遇到过不少开发者,一上来就选16:9,觉得「看着舒服」。结果拍出来的照片,实际像素比Sensor标称的低了一大截。为什么?因为16:9是裁切出来的,没用上Sensor的全部面积。
注意:选16:9或1:1,意味着你放弃了Sensor的部分像素。如果你需要最高画质,请用4:3。
23.3 选择策略:什么时候用什么
嗯,这里要讲点实战经验了。我个人的习惯是这样的:
场景一:拍照为主
用4:3。这是Sensor的原生比例,能用到所有像素点。你想想看,花大价钱买的12MP Sensor,结果只用了一半像素,多亏啊。
场景二:视频录制
用16:9。视频标准就是16:9,你硬要用4:3,播放时两边会有黑边。不过要注意,选16:9预览分辨率时,图片分辨率最好也匹配,不然取景器里看到的东西和拍出来的不一样。
场景三:社交分享
1:1。Instagram、朋友圈这些地方,正方形图片最省事。但说实话,我建议还是用4:3拍完再裁,这样后期有更多调整空间。
我的建议:预览分辨率用16:9(取景器看着舒服),图片分辨率用4:3(保留全部像素)。两者比例不同?没关系,取景器里看到的会多裁切一些,但拍出来的照片内容更丰富。
23.4 代码实现:如何获取和设置分辨率
光说不练假把式。来看看代码怎么写。
// 获取摄像头支持的预览分辨率列表
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
StreamConfigurationMap configMap = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] previewSizes = configMap.getOutputSizes(SurfaceTexture.class);
Size[] pictureSizes = configMap.getOutputSizes(ImageFormat.JPEG);
// 选择最佳预览分辨率(优先选16:9,且不超过屏幕尺寸)
Size optimalPreviewSize = chooseOptimalSize(previewSizes, displayWidth, displayHeight, new Size(1920, 1080));
// 选择最佳图片分辨率(优先选4:3,且用Sensor最大尺寸)
Size optimalPictureSize = chooseOptimalSize(pictureSizes, sensorWidth, sensorHeight, new Size(4000, 3000));
// 设置到CaptureRequest
previewRequestBuilder.set(CaptureRequest.JPEG_QUALITY, (byte) 100);
// 注意:图片分辨率在CaptureSession创建时通过ImageReader设置
imageReader = ImageReader.newInstance(optimalPictureSize.getWidth(), optimalPictureSize.getHeight(), ImageFormat.JPEG, 1);
这段代码里,chooseOptimalSize是个工具方法,核心逻辑就是:遍历所有支持的分辨率,找到最接近目标尺寸的那个。我习惯先按比例过滤,再按面积排序。
23.5 避坑指南
我曾经在一个项目里,预览和图片都用了Sensor最大分辨率。结果呢?取景器卡成PPT,拍照后处理时间长得吓人。后来才意识到,预览分辨率不需要那么大,1080p就够用了。
还有一次,用户反馈说「拍出来的照片和取景器看到的不一样」。一查,预览是16:9,图片是4:3。取景器里看到的画面,左右两边比实际照片多了一些内容。嗯,这个问题其实无解,只能让用户理解两者的区别。
常见坑:
- 预览分辨率设太大 → 卡顿、发热
- 图片分辨率设太小 → 画质损失
- 预览和图片比例不一致 → 取景器所见非所得
- 选了Sensor不支持的尺寸 → 崩溃或黑屏
23.6 知识体系图
下面这张图,把分辨率选择的整个逻辑串起来了。建议保存下来,做项目时对照着看。
23.7 总结
分辨率选择这事儿,说白了就是平衡。平衡画质、性能、用户体验。我个人习惯是:预览用16:9的1080p,图片用4:3的Sensor最大分辨率。这样取景器看着舒服,拍出来的照片也保留了全部细节。
如果你刚开始接触,建议先拿一个固定机型测试。把支持的分辨率列表打出来,一个个试。试多了,自然就知道怎么选了。
一句话记住:Sensor分辨率是上限,预览分辨率看流畅,图片分辨率看需求。比例选4:3最稳妥,除非你有特殊场景。
公众号:蓝海资料掘金营,微信deep3321