簡體   English   中英

在不中斷預覽的情況下切換Camera2中的手電筒

[英]Toggle Flashlight in Camera2 without Interrupting Preview

剛開始使用Camera2框架是因為它提供了對照相機底層功能的增強控制。 但是,我在快速打開和關閉手電筒時遇到一些麻煩。 使用舊的Camera API,我可以通過以下方式在提供預覽的同時切換閃光燈:

try
{
    android.hardware.Camera.Parameters parameters = c.getParameters();
    if (parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_OFF))
    {
        parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
        Log.i("HeartBeatAlgorithm", "LightOn");
    }
    else if (parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_TORCH))
    {
        parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
        Log.i("HeartBeatAlgorithm", "LightOff");
    }
    c.setParameters(parameters);
}
catch (Exception exception)
{
    c.release();
    c = null;
}

並且手電筒將快速打開或關閉,而不會出現任何明顯的中斷。 但是,對於Camera2來說,閃光模式似乎是CaptureSession的屬性,這意味着需要創建一個全新的CaptureSession來更改閃光模式,即:

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

    texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
    Surface surface = new Surface(texture);
    mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

    if (mLightNowOn == true)
    {
        mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
    }
    else
    {
        mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
    }

    mPreviewRequestBuilder.addTarget(surface);
    mPreviewRequest = mPreviewRequestBuilder.build();
    mCameraDevice.createCaptureSession(Arrays.asList(surface), mSessionStateCallback, null);
}
catch (CameraAccessException e)
{
    e.printStackTrace();
}

正如開發人員文檔中提到的那樣,“創建會話是一項昂貴的操作,可能需要幾百毫秒,因為它需要配置攝像頭設備的內部管道並分配用於將圖像發送到所需目標的內存緩沖區。” 確實可以,並且在切換閃光模式時我的應用程序存在明顯的延遲。

我確實需要能夠快速切換閃光模式而又不會中斷太多預覽。 有什么辦法解決這個問題,還是由於新的API管道而不可避免?

並非每次更改閃光模式都必須創建一個全新的捕獲會話是不正確的。 相反,您可以在現有的捕獲會話上創建重復的預覽請求,而每次僅設置setNewRepeating請求,如下所示:

mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,CaptureRequest.FLASH_MODE_TORCH); ... mPreviewRequest = mPreviewRequestBuilder.build(); ... mCaptureSession.setRepeatingRequest(mPreviewRequest,captureCallBack,backgroundHandler);

您可以多次重復此序列。

似乎有點,但Ivan的輸入對我有用。

如果不是很明顯,則變量名看起來應該類似於類/接口名。 您必須在外部范圍中聲明它們。

captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);

captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
captureRequest = captureRequestBuilder.build();
cameraCaptureSession.setRepeatingRequest(captureRequest, null, backgroundHandler);

torchButton = findViewById(R.id.button);
torchButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        if(!lightOn) {
            try {
                captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
                captureRequest = captureRequestBuilder.build();
                cameraCaptureSession.setRepeatingRequest(captureRequest, null, backgroundHandler);
                lightOn = true;
            } catch (CameraAccessException e) {}
        }
        else if(lightOn) {
            try {
                captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
                captureRequest = captureRequestBuilder.build();
                cameraCaptureSession.setRepeatingRequest(captureRequest, null, backgroundHandler);
                lightOn = false;
            } catch (CameraAccessException e) {}
        }
    }
});

這樣,您將在割炬關閉的情況下開始預覽,但是可以通過單擊按鈕來控制。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM