Android 10设备Camera2 API相机特效无法应用至预览及拍摄画面的问题排查求助
我之前在Android 10设备上开发Camera2应用时,也碰到过类似的特效设置后画面无变化但API显示支持的情况,结合你的代码和踩过的坑,给你几个具体的排查和修复方向:
不要复用旧的预览请求构建器
你的代码里直接复用了previewRequestBuilder,但如果这个构建器之前被设置过其他参数(比如手动曝光、对焦),可能会和特效模式产生冲突。建议每次设置特效时,重新创建一个预览请求构建器,再把你之前调整的AWB、亮度等参数重新设置一遍,最后添加特效模式:public void setCameraEffect(int cameraEffect){ try{ mCameraCaptureSession.stopRepeating(); // 重新创建预览请求构建器 CaptureRequest.Builder newPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); // 重新设置之前的所有必要参数(比如AWB、亮度) newPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, mCurrentAwbMode); newPreviewBuilder.set(CaptureRequest.BRIGHTNESS, mCurrentBrightness); // 添加特效模式 newPreviewBuilder.set(CaptureRequest.CONTROL_EFFECT_MODE, cameraEffect); // 必须添加预览Surface,否则新请求无输出目标 newPreviewBuilder.addTarget(mPreviewSurface); CaptureRequest previewRequest = newPreviewBuilder.build(); mCameraCaptureSession.setRepeatingRequest(previewRequest, mCaptureCallback, mHandler); } catch (Exception e){ e.printStackTrace(); } }确认特效枚举值正确且被实际应用
虽然你通过CONTROL_AVAILABLE_EFFECTS看到特效支持,但要确保传入的cameraEffect是Camera2标准常量(比如CONTROL_EFFECT_MODE_MONO、CONTROL_EFFECT_MODE_NEGATIVE),不要用自定义int值。另外,可以在捕获回调里验证相机是否真的接收了参数:@Override public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) { Integer appliedEffect = result.get(CaptureResult.CONTROL_EFFECT_MODE); Log.d("CameraDebug", "实际应用的特效模式:" + appliedEffect); }确保相机控制模式兼容
Android 10上部分设备的Camera2特效依赖自动控制模式,如果你的预览请求设置了CONTROL_MODE_OFF(手动控制所有参数),特效可能无法生效。建议显式设置控制模式为自动:newPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);若需要保留部分手动参数,可以尝试
CONTROL_MODE_USE_SCENE_MODE搭配手动设置,具体要看设备支持的组合。等待Session停止重复捕获后再更新请求
stopRepeating()是异步操作,立刻调用setRepeatingRequest()可能导致新请求被旧请求覆盖。可以先终止所有未完成捕获,再延迟更新请求:mCameraCaptureSession.stopRepeating(); mCameraCaptureSession.abortCaptures(); // 终止所有未完成的捕获 mHandler.postDelayed(() -> { try { mCameraCaptureSession.setRepeatingRequest(previewRequest, mCaptureCallback, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); } }, 100);检查预览Surface的格式兼容性
有些特效需要特定图像格式(比如YUV_420_888)支持,如果预览Surface用了设备不兼容的格式(比如RGB_565),特效也不会生效。可以通过以下代码查看设备支持的预览格式:StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); int[] supportedFormats = map.getOutputFormats(); for (int format : supportedFormats) { Log.d("CameraDebug", "支持的格式:" + ImageFormat.formatToString(format)); }
内容的提问来源于stack exchange,提问作者Talha Ç

