在Camera2 API中,你可以通过创建一个CameraCaptureSession绑定到一个SurfaceView或TextureView来显示相机预览。 不幸的是,一些参数(如对比度和伽玛)只对JPEG格式的图像生效,而不适用于预览。
解决方法是使用RenderScript或OpenGL ES处理捕获的帧,然后将结果显示在预览界面上。 这有助于我们在捕获帧后应用不同的滤镜。 例如,您可以使用RenderScript的ColorMatrix来应用对比度/伽马校正,如下所示:
private void createCameraPreviewSession() {
try {
SurfaceTexture texture = mTextureView.getSurfaceTexture();
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface surface = new Surface(texture);
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mCameraDevice.createCaptureSession(Arrays.asList(surface),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
// When the session is ready, we start displaying the preview.
mCaptureSession = cameraCaptureSession;
try {
// Auto focus should be continuous for camera preview.
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// Set the filter for contrast and gamma correction.
RenderScript rs = RenderScript.create(getContext());
byte[] colorMatrix = {
vp, 0, 0, 0, 0, // Red
0, vp, 0, 0, 0, // Green
0, 0, vp, 0, 0, // Blue
0, 0, 0, 1, 0}; // Alpha
ScriptIntrinsicColorMatrix matrix = ScriptIntrinsicColorMatrix.create(rs);
matrix.setColorMatrix(new Matrix4f(colorMatrix));
matrix.setAdd(5f/255f);
matrix.forEach(new Allocation(rs, Allocation.USAGE_SCRIPT), new Allocation(rs, Allocation.USAGE_SCRIPT));
rs.finish();
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE_ON);
// Update auto-exposure with FRAME_CONTROL.
mPreviewRequestBuilder.setFrameDuration(250000);
cameraCaptureSession.setRepeatingRequest(mPreviewRequestBuilder