Camera2使用surface支持
阅读原文时间:2023年07月08日阅读:1

surfaceview是运行在子线程,可以为相机提供不断的刷新

public class MainActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

    getSupportFragmentManager().beginTransaction().add(R.id.relative, new BlankFragment()).commit();

}

}

主activity用于启动一个Fragment在fragment中启动相机

public class BlankFragment extends Fragment {

public static final int REQUEST\_CAMERA\_CODE = 100;  
public static final String PACKAGE = "package:";

private static final SparseIntArray ORIENTATIONS = new SparseIntArray();

///为了使照片竖直显示  
static {  
    ORIENTATIONS.append(Surface.ROTATION\_0, 90);  
    ORIENTATIONS.append(Surface.ROTATION\_90, 0);  
    ORIENTATIONS.append(Surface.ROTATION\_180, 270);  
    ORIENTATIONS.append(Surface.ROTATION\_270, 180);  
}

private SurfaceView mSurfaceView;  
private SurfaceHolder mSurfaceHolder;  
private ImageView iv\_show;  
private ImageView mCatture;  
private CameraManager mCameraManager;//摄像头管理器  
private Handler childHandler, mainHandler;  
private String mCameraID;//摄像头Id 0 为后  1 为前  
private ImageReader mImageReader;  
private CameraCaptureSession mCameraCaptureSession;  
private CameraDevice mCameraDevice;  
/\*\*  
 \* 摄像头创建监听  
 \*/  
private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {  
    @Override  
    public void onOpened(CameraDevice camera) {//打开摄像头  
        mCameraDevice = camera;  
        //开启预览  
        takePreview();  
    }

    @Override  
    public void onDisconnected(CameraDevice camera) {//关闭摄像头  
        if (null != mCameraDevice) {  
            mCameraDevice.close();  
           mCameraDevice = null;  
        }  
    }

    @Override  
    public void onError(CameraDevice camera, int error) {//发生错误  
        Toast.makeText(getContext(), "摄像头开启失败", Toast.LENGTH\_SHORT).show();  
    }  
};

public static BlankFragment newInstance() {  
    return new BlankFragment();  
}

@Nullable  
@Override  
public View onCreateView(LayoutInflater inflater, ViewGroup container,  
                         Bundle savedInstanceState) {  
    View root = inflater.inflate(R.layout.fragment\_blank, container, false);  
    initVIew(root);  
    initListener();  
    return root;  
}

@Override  
public void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
}

@Override  
public void onResume() {  
    super.onResume();  
}

/\*\*  
 \* 初始化  
 \*/  
private void initVIew(View root) {  
    iv\_show = (ImageView) root.findViewById(R.id.iv\_show\_camera2);  
    //mSurfaceView  
    mSurfaceView = (SurfaceView) root.findViewById(R.id.surface\_view\_camera2);  
    mCatture = (ImageView) root.findViewById(R.id.capture);  
    mSurfaceHolder = mSurfaceView.getHolder();  
    mSurfaceHolder.setKeepScreenOn(true);  
    // mSurfaceView添加回调  
    mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {  
        @Override  
        public void surfaceCreated(SurfaceHolder holder) { //SurfaceView创建  
            // 初始化Camera  
            initCamera2();  
        }

        @Override  
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
        }

        @Override  
        public void surfaceDestroyed(SurfaceHolder holder) { //SurfaceView销毁  
            // 释放Camera资源  
            if (null != mCameraDevice) {  
                mCameraDevice.close();  
             mCameraDevice = null;  
            }  
        }  
    });  
}

/\*\*  
 \* 初始化Camera2  
 \*/  
@RequiresApi(api = Build.VERSION\_CODES.LOLLIPOP)  
private void initCamera2() {  
    HandlerThread handlerThread = new HandlerThread("Camera2");  
    handlerThread.start();  
    childHandler = new Handler(handlerThread.getLooper());  
    mainHandler = new Handler(getMainLooper());  
    mCameraID = "" + CameraCharacteristics.LENS\_FACING\_FRONT;//后摄像头  
    mImageReader = ImageReader.newInstance(1080, 1920, ImageFormat.JPEG, 1);  
    mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() { //可以在这里处理拍照得到的临时照片 例如,写入本地  
        @Override  
        public void onImageAvailable(ImageReader reader) {  
            //mCameraDevice.close();  
            // 拿到拍照照片数据  
            Image image = reader.acquireNextImage();  
            ByteBuffer buffer = image.getPlanes()\[0\].getBuffer();  
            byte\[\] bytes = new byte\[buffer.remaining()\];  
            buffer.get(bytes);//由缓冲区存入字节数组  
            final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);  
            if (bitmap != null) {  
                iv\_show.setImageBitmap(bitmap);  
            }  
        }  
    }, mainHandler);  
    //获取摄像头管理  
    mCameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA\_SERVICE);  
    try {  
        if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION\_GRANTED) {  
            //申请WRITE\_EXTERNAL\_STORAGE权限  
            requestPermissions(new String\[\]{Manifest.permission.CAMERA},  
                    REQUEST\_CAMERA\_CODE);  
            //return;  
        } else {  
            //打开摄像头  
            mCameraManager.openCamera(mCameraID, stateCallback, mainHandler);

        }  
    } catch (CameraAccessException e) {  
        e.printStackTrace();  
    }  
}

@Override  
public void onRequestPermissionsResult(int requestCode, String\[\] permissions, int\[\] grantResults) {  
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);  
    if (requestCode == REQUEST\_CAMERA\_CODE) {  
        if (grantResults\[0\] == PackageManager.PERMISSION\_GRANTED) {  
            // Permission Granted  
            try {  
                mCameraManager.openCamera(mCameraID, stateCallback, mainHandler);  
            } catch (CameraAccessException e) {  
                e.printStackTrace();  
            } catch (SecurityException e) {  
                e.printStackTrace();  
            }  
        } else {  
            // Permission Denied  
        }  
    }  
}

/\*\*  
 \* 开始预览  
 \*/  
private void takePreview() {  
    try {  
        // 创建预览需要的CaptureRequest.Builder  
        final CaptureRequest.Builder previewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE\_PREVIEW);  
        // 将SurfaceView的surface作为CaptureRequest.Builder的目标  
        previewRequestBuilder.addTarget(mSurfaceHolder.getSurface());  
        // 创建CameraCaptureSession,该对象负责管理处理预览请求和拍照请求  
        mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface(), mImageReader.getSurface()), new CameraCaptureSession.StateCallback() // ③  
        {  
            @Override  
            public void onConfigured(CameraCaptureSession cameraCaptureSession) {  
                if (null == mCameraDevice) return;  
                // 当摄像头已经准备好时,开始显示预览  
                mCameraCaptureSession = cameraCaptureSession;  
                try {  
                    // 自动对焦  
                    previewRequestBuilder.set(CaptureRequest.CONTROL\_AF\_MODE, CaptureRequest.CONTROL\_AF\_MODE\_CONTINUOUS\_PICTURE);  
                    // 打开闪光灯  
                    previewRequestBuilder.set(CaptureRequest.CONTROL\_AE\_MODE, CaptureRequest.CONTROL\_AE\_MODE\_ON\_AUTO\_FLASH);  
                    // 显示预览  
                    CaptureRequest previewRequest = previewRequestBuilder.build();  
                    mCameraCaptureSession.setRepeatingRequest(previewRequest, null, childHandler);  
                } catch (CameraAccessException e) {  
                    e.printStackTrace();  
                }  
            }

            @Override  
            public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {  
                Toast.makeText(getContext(), "配置失败", Toast.LENGTH\_SHORT).show();  
            }  
        }, childHandler);  
    } catch (CameraAccessException e) {  
        e.printStackTrace();  
    }  
}

/\*\*  
 \* 拍照  
 \*/  
private void takePicture() {  
    if (mCameraDevice == null) return;  
    // 创建拍照需要的CaptureRequest.Builder  
    final CaptureRequest.Builder captureRequestBuilder;  
    try {  
        captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE\_STILL\_CAPTURE);  
        // 将imageReader的surface作为CaptureRequest.Builder的目标  
        captureRequestBuilder.addTarget(mImageReader.getSurface());  
        // 自动对焦  
        captureRequestBuilder.set(CaptureRequest.CONTROL\_AF\_MODE, CaptureRequest.CONTROL\_AF\_MODE\_CONTINUOUS\_PICTURE);  
        // 自动曝光  
        captureRequestBuilder.set(CaptureRequest.CONTROL\_AE\_MODE, CaptureRequest.CONTROL\_AE\_MODE\_ON\_AUTO\_FLASH);  
        // 获取手机方向  
        int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();  
        // 根据设备方向计算设置照片的方向  
        captureRequestBuilder.set(CaptureRequest.JPEG\_ORIENTATION, ORIENTATIONS.get(rotation));  
        //拍照  
        CaptureRequest mCaptureRequest = captureRequestBuilder.build();  
        mCameraCaptureSession.capture(mCaptureRequest, null, childHandler);  
    } catch (CameraAccessException e) {  
        e.printStackTrace();  
    }  
}

private void initListener() {  
    mCatture.setOnClickListener(new View.OnClickListener() {  
        @Override  
        public void onClick(View v) {  
            takePicture();  
        }  
    });  
}

}





<SurfaceView  
    android:id="@+id/surface\_view\_camera2"  
    android:layout\_width="match\_parent"  
    android:layout\_height="match\_parent"/>

上面是fragment的布局,activity的布局是空的,只有一个id  relative