【问题标题】:Why turning on flash change the focus mode of the camera?为什么打开闪光灯会改变相机的对焦模式?
【发布时间】:2019-06-12 11:48:24
【问题描述】:

我有 2 个 AF 焦距,可以通过按钮和一个闪光灯开关来控制。

为什么updatePreview() 中的手电筒IF ELSE 会影响自动对焦模式?当我注释掉那部分(手电筒的 IF ELSE)时,AF 模式和对焦距离与 btnFocus 配合得很好。

如何解决这个问题,同时还能让用户打开和关闭手电筒?

    private float focusDistance = 0;
    private int flashSwitch = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textureView = (TextureView)findViewById(R.id.textureView);
        //From Java 1.4 , you can use keyword 'assert' to check expression true or false
        assert textureView != null;
        textureView.setSurfaceTextureListener(textureListener);
        btnFocus = (Button)findViewById(R.id.btnFocus);
        btnFlash = (Button)findViewById(R.id.btnFlash);
        btnFocus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                changeFocus();
            }
        });
        btnFlash.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                Flash();
            }
        });
    }

    private void Flash() {
        if(cameraDevice == null)
            return;
        if(flashSwitch == 0 ) {
            Toast.makeText(MainActivity.this, "Flash Turn On ", Toast.LENGTH_SHORT).show();
            flashSwitch = 1;
        }
        else{
            Toast.makeText(MainActivity.this, "Flash Turn Off ", Toast.LENGTH_SHORT).show();
            flashSwitch = 0;
        }
        createCameraPreview();
    }


    private void changeFocus() {
        if(cameraDevice == null)
            return;
        if(focusDistance == 0 )
            focusDistance = 10;
        else
            focusDistance = 0;
        Toast.makeText(MainActivity.this, "Focus Change "+ focusDistance, Toast.LENGTH_SHORT).show();
        createCameraPreview();
    }

    private void createCameraPreview() {
        try{
            SurfaceTexture texture = textureView.getSurfaceTexture();
            assert  texture != null;
            texture.setDefaultBufferSize(imageDimension.getWidth(),imageDimension.getHeight());
            Surface surface = new Surface(texture);
            captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            captureRequestBuilder.addTarget(surface);
            cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                    if(cameraDevice == null)
                        return;
                    cameraCaptureSessions = cameraCaptureSession;
                    updatePreview();
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
                    Toast.makeText(MainActivity.this, "Changed", Toast.LENGTH_SHORT).show();
                }
            },null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

如果你取消注释部分,当打开闪光灯并改变焦点时就会出现问题。

    private void updatePreview() {
        if(cameraDevice == null)
            Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
        try{
//            if you uncomment this part the problem will come out 
//            if(flashSwitch == 0){
//                captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
//            }
//            else{
//                captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
//            }
            captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_OFF);
            captureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, focusDistance);
            cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(),null,mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

预期输出

可以在不影响对焦模式的情况下手动开启和关闭闪光灯。

【问题讨论】:

  • 也许您想将 Flash() 更改为 flash()switchFlash() 以符合驼峰式大小写约定。

标签: java android android-camera2


【解决方案1】:

我认为您的问题可能出在您设置请求的方式上。 您应该首先创建一次预览,并且只创建一次,按照您的方式,您每次切换闪光灯和/或焦点时都会创建一个预览。 我建议在onStart 中创建预览,并使用一些默认值,例如:

focusDistance = 0;
flashSwitch = CaptureRequest.FLASH_MODE_OFF;

然后在 Flash() 和 changeFocus() 中调用 createCameraPreview() 而不是调用 updatePreview(),您的更新预览将如下所示:

private void updatePreview() {
        if(cameraDevice == null)
            Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
        try{
            captureRequestBuilder.set(CaptureRequest.FLASH_MODE, flashSwitch);
            captureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, focusDistance);    
            cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(),null,mBackgroundHandler);

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

【讨论】:

  • 您好,可以分享一下您的联系方式吗?因为我想询问如何将预览中的每一帧都作为位图进行处理。我是一名自学成才的 android 开发人员,从事图像处理。
  • 我给你发了邮件,如果你没有收到请告诉我。希望尽快收到您的来信。
【解决方案2】:

updatePreview() 中,您在解决captureRequestBuilder 中的所有密钥之前向cameraCaptureSessions 发送多个捕获请求。尝试先设置所有键,然后发送一个重复捕获请求。

private void updatePreview() {
        if(cameraDevice == null)
            Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
        try{
            if(flashSwitch == 0){
                captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
            }
            else{
                captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
            }
            captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_OFF);
            captureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, focusDistance);

            cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(),null,mBackgroundHandler);

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

【讨论】:

  • 等我上班的时候试试看,你介意看看这个吗? link
猜你喜欢
  • 1970-01-01
  • 2015-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-03
  • 2011-06-11
相关资源
最近更新 更多