Android Camera2官方demo的学习

一.介绍:

Camera2 是 Android L 的一个重大更新,重新定义了相机 API,也重构了相机 API 的架构,但使用起来,还是很复杂。 官方demo地址:Camera2

二.流程:

在这里插入图片描述
下面根据官方demo来详细了解下Camera2的拍照流程

1.设置预览图的尺寸
   mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
                        rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
                        maxPreviewHeight, largest);
2.创建一个用于处理拍照图片处理的ImageReder
   mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
                        ImageFormat.JPEG, /*maxImages*/2);
                mImageReader.setOnImageAvailableListener(
                        mOnImageAvailableListener, mBackgroundHandler);

这里会为ImageReder设置一个OnImageAvailableListener的监听器,一旦ImageReder获取到相机设备传过来的图像,就会回调该监听器的onImageAvailable方法,在onImageAvailable方法的ImageReader参数就携带了拍照所得的图像

  private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
            = new ImageReader.OnImageAvailableListener() {

        @Override
        public void onImageAvailable(ImageReader reader) {
            mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile));
        }

    };

3.获取CamerManager对象,并打开相机设备
  CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
        try {
        //这里把相机加了一把锁,因为可能会有多个应用用到相机设备,在指定时间内,没有拿到许可就会抛异常
            if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {  
                throw new RuntimeException("Time out waiting to lock camera opening.");
            }
//这里回传入一个CameraDevice.StateCallback对象mStateCallback,这个就是拿到相机设备成功失败的回调
            manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
        }
4.获取到相机设备,创建用于显示预览图片的Surface和一个适合相机预览窗口的请求
 SurfaceTexture texture = mTextureView.getSurfaceTexture();
            assert texture != null;

            // We configure the size of default buffer to be the size of camera preview we want.
            texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

            // This is the output Surface we need to start preview.
            Surface surface = new Surface(texture);

            // We set up a CaptureRequest.Builder with the output Surface.
            mPreviewRequestBuilder
                    = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            mPreviewRequestBuilder.addTarget(surface);
5.创建一个CameraCaptureSession
/**
第一个参数List<Surface>,surface用于显示预览图的,就是第四步中创建的那个Surface,mImageReader.getSurface()使用来处理拍照返回的图片的Surface,

第二个参数callback, CameraCaptureSession.StateCallback对象,创建session成功与否的回调

第三个参数,Handler指定回调的线程,null表示当前线程
*/
mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),callback, mImageReader.getSurface()),
                  , null
            );
6.在 CameraCaptureSession.StateCallback接收到CameraCaptureSession并发送预览请求,
 new CameraCaptureSession.StateCallback() {

                        @Override
                        public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                            // The camera is already closed
                            if (null == mCameraDevice) {
                                return;
                            }

                            // 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);
                                // Flash is automatically enabled when necessary.
                                setAutoFlash(mPreviewRequestBuilder);

                                // Finally, we start displaying the camera preview.
                                mPreviewRequest = mPreviewRequestBuilder.build();
// 通过此捕获会话无休止地重复捕获图像,即预览请求                              mCaptureSession.setRepeatingRequest(mPreviewRequest,
                                        mCaptureCallback, mBackgroundHandler);
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onConfigureFailed(
                                @NonNull CameraCaptureSession cameraCaptureSession) {
                            showToast("Failed");
                        }
                    }

到此,我们的TextureView就可以显示预览的图像了

7.拍照
  try {
            // This is how to tell the camera to lock focus,自动对焦
           mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CameraMetadata.CONTROL_AF_TRIGGER_START);
            // Tell #mCaptureCallback to wait for the lock.
            mState = STATE_WAITING_LOCK;
//提交要由相机设备捕获的图像的请求            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

在mCaptureCallback中,调用captureStillPicture()

 private void captureStillPicture() {
        try {
            final Activity activity = getActivity();
            if (null == activity || null == mCameraDevice) {
                return;
            }
            // This is the CaptureRequest.Builder that we use to take a picture.
            final CaptureRequest.Builder captureBuilder =
                    mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);

//将mImageReader的surface添加到此请求的目标列表中,这时拍照所返回的图片就会交由mImageReader的mOnImageAvailableListener处理
            captureBuilder.addTarget(mImageReader.getSurface());

            // Use the same AE and AF modes as the preview.
            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            setAutoFlash(captureBuilder);

            // Orientation
            int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));

            CameraCaptureSession.CaptureCallback CaptureCallback
                    = new CameraCaptureSession.CaptureCallback() {

//拍照事务完成后回调这个方法
                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                               @NonNull CaptureRequest request,
                                               @NonNull TotalCaptureResult result) {
                    showToast("Saved: " + mFile);
                    Log.d(TAG, mFile.toString());
                    unlockFocus();
                }
            };

            mCaptureSession.stopRepeating();
            mCaptureSession.abortCaptures();
            mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

至此,拍照也已完成

三.总结

这仅仅是对谷歌Camera2官方Demo的一个简单学习,关于Camera2中的各种操作还有许多学习的地方,包括美颜,磨皮各种模式的实现

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Camera2 Demo是一个展示了如何使用Android相机API的示例应用程序。该示例应用程序基于Android 5.0(API 21)及更高版本的Android平台。它展示了如何使用Camera2 API来实现高级功能,如手动对焦、手动曝光、RAW图像捕获等。 首先,在应用程序的布局文件中,我们需要添加一个TextureView来显示相机预览画面。然后,在MainActivity中,我们需要创建一个CameraManager的实例,以获取设备上的相机列表。接下来,我们需要实现一个CameraDevice.StateCallback来处理相机设备的打开和关闭。 当我们选择一个相机设备时,我们可以通过CameraManager的openCamera方法打开相机。然后,我们可以创建一个CaptureRequest.Builder来构建捕获请求,设置相机参数和预览目标。我们还需要创建一个CameraCaptureSession来发送捕获请求。 我们可以通过设置CaptureRequest.Builder的参数来实现手动对焦和手动曝光。例如,我们可以使用CONTROL_AF_MODE来设置对焦模式,使用CONTROL_AE_MODE和CONTROL_AE_EXPOSURE_COMPENSATION来设置曝光模式和曝光补偿。 在捕获图像时,我们可以使用ImageReader类来创建一个ImageReader实例,用于获取捕获的图像数据。我们可以在CameraCaptureSession.CaptureCallback的onCaptureCompleted回调方法中处理捕获的图像数据,并将其保存到本地文件中。 此外,我们还可以使用CameraCharacteristics类来获取相机设备的特性,如支持的对焦模式、支持的曝光模式等。我们还可以使用CameraMetadata类来设置相机参数,如对焦区域、曝光补偿等。 总之,Android Camera2 Demo演示了如何使用Camera2 API来创建一个全功能相机应用程序。它展示了如何打开相机、设置相机参数、捕获图像并处理图像数据。通过学习和理解这个示例应用程序,我们可以更好地了解和使用Android相机API。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值