内容 | Camera1.0 | Camera2.0 |
---|---|---|
权限 | android.permission.CAMERA | android.permission.CAMERA |
布局 | SurfaceView | TextureView |
实现接口 | SurfaceHolder.Callback 1.surfaceCreated 2.surfaceChanged 3.surfaceDestroyed | SurfaceTextureListener 1.onSurfaceTextureAvailable 2.onSurfaceTextureSizeChanged 3.onSurfaceTextureDestroyed 4.onSurfaceTextureUpdated |
Camera参数(设置,查看) | Camera.Parameters Camera.Size | 查看:CameraCharacteristics中getCameraCharacteristics(CameraID)设置:CaptureRequest.Builder中void set(Key key, T value)举例:曝光:CaptureReqBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 2); |
打开摄像头 | surfaceCreated中Camera.open(CameraID) | onSurfaceTextureAvailable中CameraManager.openCamera(CameraId,CameraDevice.StateCallback,Handler) |
开始预览 | Camera.startPreview() | CaptureReqBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);CaptureReqBuilder.addTarget(Surface);Camera.createCaptureSession(Arrays.asList(surface),CaptureSessionStateCallback, Handler); |
设置预览方向 | Camera.setDisplayOrientation(degrees) | 并没有直接设置预览方向的方法,但是TextureView本身是一个View,支持旋转、平移、缩放,再重写onMeasure方法 |
图像原始数据byte[]实时获取 | Camera.PreviewCallback中onPreviewFrame(byte[],Camera) | 1.onSurfaceTextureUpdated中使用TextureView的getBitmap()方法,但是这里获取到的是Bitmap对象,而我需要的是原始byte[],所以这个方法不适用。2.设置ImageReader.setOnImageAvailableListener监听,在onImageAvailable(ImageReader)通过回调传递的ImageReader.acquireLatestImage()方法获取到一个Image对象(别忘了close(),否则画面会卡住,停止刷新),然后Image.getPlanes()[0].getBuffer()返回了一个ByteBuffer对象,最后new byte[buffer.remaining()]即可得到原始图像的byte[]。别忘了CaptureReqBuilder.addTarget(ImageReader.getSurface()); 否则看不到效果 |
Camera图像预览尺寸大小设置 | Camera.Parameters.setPreviewSize(width, height) | TextureView. getSurfaceTexture()拿到SurfaceTexture()对象,再通过setDefaultBufferSize(width, height)进行设置。 |
将来获取到的图片的大小设置 | Camera.Parameters.setPictureSize(width, height); | ImageReader.newInstance(width, height,ImageFormat.YUV_420_888, MAX_IMAGES); |
将来获取到的图片的格式设置 | Camera.Parameters..setPictureFormat(ImageFormat.JPEG); | ImageReader.newInstance(width, height,ImageFormat.YUV_420_888, MAX_IMAGES); |
- Camera2是通过系统服务拿到CameraManager来管理camera设备对象,camera的一次预览、拍照都是向请求会话(CaptureSession.StateCallback,摄像头打开时由相机设备的输出surface组成)发送一次请求(CaptureRequest.Builder)。需要在它的回调onConfigured中进行处理,例如预览,如果不在此方法中写上CameraCaptureSession.setRepeatingRequest(mCaptureReqBuilder.build(), null, mHandler);那么预览就不会成功。
- 此外,在创建会话,设置ImageReader监听,都需要传递一个Handler对象,这个Handler对象决定着这些会话、监听的回调方法会被在哪个线程中调用,如果传递的是NULL,那么回调会调用在当前线程。
闪关灯的控制方式
Camera1:
这句代码可以得到摄像头支持的闪光灯模式
List supportedFlashModes = params.getSupportedFlashModes();
控制闪光灯的方法:
params.setFlashMode(Parameters.FLASH_MODE_TORCH );//开启闪光灯
Parameters.FLASH_MODE_TORCH : 闪光灯常开
Parameters.FLASH_MODE_ON :拍照时闪光灯才打开
Camera2:
这句代码可以用来检测当前打开的摄像头是否支持闪光灯
boolean flashAvailable = cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
控制闪光灯的方法:
case 0: mBtnFlash.setImageResource(R.drawable.btn_flash_off); mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON); mPreviewBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF); break; case 1: mBtnFlash.setImageResource(R.drawable.btn_flash_on); mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON); mPreviewBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_SINGLE); break; case 2: mBtnFlash.setImageResource(R.drawable.btn_flash_all_on); mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON); mPreviewBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH); break;