当前位置: 首页 > 知识库问答 >
问题:

在Camera2上的捕获会话期间启用预览

梁丘翔
2023-03-14

我正在构建一个基于Camera2的相机应用程序,但我保存的图片与我在surface View上看到的最新一张不匹配。预览会话似乎可以工作,但当我请求捕获时,新请求停止预览并捕获图像。surface view冻结在最新的pic上,并且在我按下快门按钮(预览运行和请求捕获)和捕获请求的onCaptureCompleted之间创建了一个间隙。

这是预览会话

private void createCameraPreviewSession() {

    try {

        SurfaceTexture texture = mTextureView.getSurfaceTexture();
        assert texture != null;

        texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

        Log.d(TAG, "here is the width of texture" + mPreviewSize.getWidth());
        Log.d(TAG, "here is the height of texture" +mPreviewSize.getHeight());

        Surface surface = new Surface(texture);

        mPreviewRequestBuilder
                = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        mPreviewRequestBuilder.addTarget(surface);

        mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
                new CameraCaptureSession.StateCallback() {

                    @Override
                    public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                        if (null == mCameraDevice) {
                            return;
                        }

                        mCaptureSession = cameraCaptureSession;
                        try {
                            mPreviewRequest = mPreviewRequestBuilder.build();
                            mCaptureSession.setRepeatingRequest(mPreviewRequest,
                                    mCaptureCallback, mBackgroundHandler);
                        } catch (CameraAccessException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onConfigureFailed(
                            @NonNull CameraCaptureSession cameraCaptureSession) {
                        showToast("Failed");
                    }
                }, null
        );
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}
    private void process(CaptureResult result) {
        switch (mState) {
            case STATE_PREVIEW:
                break;

            case STATE_CAPTURE:
                mState = STATE_PREVIEW;
                capturePicture();
                break;
        }
    }

    @Override
    public void onCaptureProgressed(@NonNull CameraCaptureSession session,
                                    @NonNull CaptureRequest request,
                                    @NonNull CaptureResult partialResult) {

        process(partialResult);
    }


    @Override
    public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                   @NonNull CaptureRequest request,
                                   @NonNull TotalCaptureResult result) {
        TotalCaptureResult iResult = result;
        Log.d(TAG, "Frame on Completed: "+result.getFrameNumber());
        process(result);
    }
}

现在的情况是,我重复预览,它起作用了。这个进程只是用来保持它的运行,在mState设置为capture之前什么都没有发生。

它被设置为当我们点击快门按钮时捕捉。当我点击按钮时,我调用:

private void takePicture(){
        try {
            mFile = ImageSaver.generateNewFileImage();
            mState = STATE_CAPTURE;
            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
        } catch (CameraAccessException e) {
            Log.e(TAG,"Camera exception",e);
        }
    }

然后调用CapturePicture,因为mState在mCaptureCallback中定义的捕获中

private void capturePicture() {
    mTakePictureRunnable = new Runnable() {
        @Override
        public void run() {
            takePictureNow();
        }
    };
    mBackgroundHandler.post(mTakePictureRunnable);
}
private void takePictureNow() {

    Log.d(TAG, "Running captureStillPicture");

    try {
        if (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());

        SurfaceTexture texture = mTextureView.getSurfaceTexture();
        assert texture != null;

        texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

        Log.d(TAG, "here is the width of texture" + mPreviewSize.getWidth());
        Log.d(TAG, "here is the height of texture" + mPreviewSize.getHeight());

        Surface surface = new Surface(texture);
        captureBuilder.addTarget(surface);


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

        //Location if needed
        boolean Location_Saved = CameraSettings.Instance().getBoolean(CameraSettings.SAVE_LOCATION,
                getResources().getBoolean(R.bool.action_camera_settings_dflt_location));

        if(Location_Saved == true) {
            captureBuilder.set(CaptureRequest.JPEG_GPS_LOCATION, mLocationManager.getCurrentLocation());
        } else {
            captureBuilder.set(CaptureRequest.JPEG_GPS_LOCATION, null);
        }


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

            @Override
            public void onCaptureStarted(@NonNull CameraCaptureSession session,
                                         @NonNull CaptureRequest request,
                                         @NonNull long timestamp,
                                         @NonNull long framenumber) {
                playShutterSound();
                showShutterAnimation();

            }

            @Override
            public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                           @NonNull CaptureRequest request,
                                           @NonNull TotalCaptureResult result) {
                Log.d(TAG, mFile.toString());
                mState = STATE_PREVIEW;
            }
        };

        mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
        mCaptureSession.stopRepeating();

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

似乎捕获没有更新表面和表面只显示时,我们在预览

想看看我存了什么吗?谢谢

共有1个答案

袁高明
2023-03-14

当你拍摄一张图像时,表面会冻结,这张图像可能不是被保存的图像。如果你还想在屏幕上显示相机预览,你只需要通过调用你在第一时间用来创建预览的函数来重新启动相机预览。

 类似资料:
  • 是否有可能“拦截”会话超时? 我尝试了,但据我所知,当调用HttpSessionListener.session毁灭()'方法时,会话已经被摧毁。(所以我没有机会确定用户,拥有超时的会话) 另一个选项是PhaseListener,在restoreView阶段检查会话是否是“新的”。 但是,我需要在会话超时的“第二天”执行一些操作-不在以后的刷新中执行,也不在以后的登录中执行。 (背景:需要删除某些

  • 我的MySQL不会启动,它显示如下: 然后是错误日志: 这些错误的原因是什么?我如何纠正它们?

  • 问题内容: 我正在尝试修改android-Camera2Basic代码以捕获一连串的图片。但是,在运行L 5.0.1的Nexus 5上,图片之间的延迟不会超过200-300ms。 我已经尝试了很多东西,但这是最基本的。这是我修改过的Camera2Basic代码的唯一部分。我的预览TextureView只有50x50dp,但这没关系,对吧? 就其价值而言,此代码在我的Nexus 6(带有L 5.1)

  • 问题内容: 有没有一种方法可以打印在Django Shell会话期间Django ORM执行的原始SQL查询的数量? Django调试工具栏已经提供了这类信息(例如,但如何从shell中获取信息尚不明显。 问题答案: 您可以使用:

  • 但是为了全屏显示相机预览,我将TextureView更改为match_parent。这样做,输出就改变了。现在预览的相机是不同的图像捕获。 请检查这里附上的图像。 1、相机预览:-相机预览截图 我也尝试在camera preview builder和image reader中设置CaptureRequest.Scaler_Crop_Region,但它没有像预期的那样工作。

  • 使用Spring 我的服务: 后来我实现了一些逻辑: 但它没有捕获关于重复密钥的报告的异常: 所以,我的角色并没有被扔出去。我的角色已经不存在了。在服务结束方法的事务提交期间引发异常。如何捕捉异常???或者如何以另一种方式在Spring中实现这种逻辑??