在不阻止预览相机2 api 的情况下,在后台从相机预览中捕获图片的可能方法



所以,事情是这样的。我试图在自动对焦锁定后立即从相机预览中获取照片。我现在能够做到这一点,而且效果很好。现在,在捕获图片时,它会暂时阻止预览。我想在不阻止预览的情况下完成整个捕获过程。有没有办法去做?

这是我当前的代码,它建立在Google示例相机2代码之上。

         boolean areWeFocused = false;
                int counter =0;
                /**
                 * A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture.
                 */
                private CameraCaptureSession.CaptureCallback mCaptureCallback
                        = new CameraCaptureSession.CaptureCallback() {
                    private void process(CaptureResult result) {
                        Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
                        switch (mState) {
                            case STATE_PREVIEW: {
                                // We have nothing to do when the camera preview is working normally.
                                if (CaptureResult.CONTROL_AF_TRIGGER_START == afState) {
                                    if (areWeFocused) {
                                        //Run specific task here
                                        counter++;

                                        takePicture();
                                        Log.d("FocussedState","I am focussed now");
                                    }
                                }
                                if (CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED == afState) {
                                    areWeFocused = true;
                                } else {
                                    areWeFocused = false;
                                    Log.d("FocussedState","I am not focussed now");
                                }
                                break;
                            }
        }
        private void takePicture() {
                lockFocus();
            }
            /**
             * Lock the focus as the first step for a still image capture.
             */
            private void lockFocus() {
                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();
                }
            }
    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);
                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();
            }
        }
  private ImageReader mImageReader;
    /**
     * This is the output file for our picture.
     */
    private File mFile;
    /**
     * This a callback object for the {@link ImageReader}. "onImageAvailable" will be called when a
     * still image is ready to be saved.
     */
    private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
            = new ImageReader.OnImageAvailableListener() {
        @Override
        public void onImageAvailable(ImageReader reader) {
            mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile));
        }
    };
  private static class ImageSaver implements Runnable {
        /**
         * The JPEG image
         */
        private final Image mImage;
        /**
         * The file we save the image into.
         */
        private final File mFile;
        ImageSaver(Image image, File file) {
            mImage = image;
            mFile = file;
        }
        @Override
        public void run() {
            ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
            byte[] bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
            FileOutputStream output = null;
            try {
                output = new FileOutputStream(mFile);
                output.write(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                mImage.close();
                if (null != output) {
                    try {
                        output.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    /**
     * Compares two {@code Size}s based on their areas.
     */
    static class CompareSizesByArea implements Comparator<Size> {
        @Override
        public int compare(Size lhs, Size rhs) {
            // We cast here to ensure the multiplications won't overflow
            return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
                    (long) rhs.getWidth() * rhs.getHeight());
        }
    }

尝试删除 captureStillPicture 末尾的 'mCaptureSession.stopRepeating((' 和 'abortCaptures'。

这些会阻止预览运行,直到重新启动,并且中止可能会导致输出出现故障。 不过,它可以稍微加快捕获时间,这可能就是它在那里的原因。

相关内容

最新更新