Android应用内置相机拍照自动裁剪且预览尺寸偏小问题排查
解决相机预览界面偏小、拍摄照片自动裁剪的问题
嘿,我来帮你捋捋这个问题——你遇到的预览界面比常规相机小、拍出来的照片自动被裁剪的情况,核心原因基本都是预览尺寸、拍照分辨率和承载预览的SurfaceView尺寸三者的比例不匹配导致的。结合你给出的surfaceChanged代码片段,咱们具体分析:
为啥会出现这种情况?
1. 预览尺寸选得不对
你代码里直接用了mPreviewSize来设置预览分辨率,但如果这个尺寸不是相机硬件原生支持的预览尺寸,或者和相机的拍照分辨率比例不一致,就会触发系统的强制适配:
- 预览画面被拉伸/压缩,看起来比正常相机预览小
- 拍摄时相机按照自身支持的拍照分辨率输出,因为和预览比例不匹配,最终照片会被自动裁剪来对齐比例
2. SurfaceView和预览尺寸比例不兼容
如果你的SurfaceView(显示预览的视图)宽高比,和你设置的预览尺寸宽高比不一样,系统会自动裁剪预览画面来适配视图,这也会让预览看起来偏小,同时拍摄的照片因为遵循相机的拍照比例,自然也会被裁剪。
怎么修复?
第一步:先拿到相机支持的合法尺寸
首先要遍历相机支持的所有预览和拍照尺寸,找到比例一致的最佳配对,避免用不兼容的尺寸:
private Camera.Size getOptimalSize(List<Camera.Size> sizes, int targetWidth, int targetHeight) { final double ASPECT_TOLERANCE = 0.1; // 比例误差容忍度 double targetRatio = (double) targetHeight / targetWidth; // 注意:相机的尺寸是按横屏定义的,所以要对应屏幕的高宽比 if (sizes == null) return null; Camera.Size optimalSize = null; double minDiff = Double.MAX_VALUE; // 优先找比例匹配且尺寸最接近目标的 for (Camera.Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // 如果没找到比例匹配的,就选尺寸最接近的 if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Camera.Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; }
第二步:在surfaceChanged里正确设置参数
确保预览尺寸和拍照尺寸的比例完全一致,同时适配SurfaceView的尺寸:
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { if (mCamera == null) return; try { Camera.Parameters parameters = mCamera.getParameters(); // 获取适配当前SurfaceView的最佳预览尺寸 List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes(); Camera.Size optimalPreviewSize = getOptimalSize(previewSizes, w, h); // 获取和预览尺寸比例一致的最佳拍照尺寸 List<Camera.Size> pictureSizes = parameters.getSupportedPictureSizes(); Camera.Size optimalPictureSize = getOptimalSize(pictureSizes, optimalPreviewSize.width, optimalPreviewSize.height); // 设置预览和拍照尺寸 parameters.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height); parameters.setPictureSize(optimalPictureSize.width, optimalPictureSize.height); // 竖屏应用别忘了设置相机显示方向,不然预览会歪 mCamera.setDisplayOrientation(90); parameters.setRotation(90); mCamera.setParameters(parameters); mCamera.startPreview(); } catch (Exception e) { e.printStackTrace(); } }
第三步:让SurfaceView适配预览比例
别给SurfaceView设固定宽高,要么用布局权重让它自适应,要么在代码里动态调整宽高,保证和预览尺寸的比例一致:
<SurfaceView android:id="@+id/camera_preview" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" />
简单来说,只要让预览尺寸、拍照尺寸、SurfaceView尺寸三者的宽高比完全对齐,就能解决预览偏小和照片被裁剪的问题啦。
内容的提问来源于stack exchange,提问作者Oktawian
相关产品推荐
相关产品推荐

