2017-10-14 301 views
3

我想使用Camera 2 API的setRepeatingRequest()模式拍攝1fps的靜態圖片。使用setRepeatingRequest的Android Camera 2 API 1fps

我將CONTROL_AE_MODE設置爲CONTROL_AE_MODE_OFFSENSOR_FRAME_DURATION1。但是,我仍然收到20fps的非常高的幀率,下面的代碼。

我試圖將捕獲請求模板從TEMPLATE_PREVIEW更改爲TEMPLATE_STILL_CAPTURE,但沒有任何運氣。我如何使用setRepeatingRequest()實現1fps?

CaptureRequest.Builder requestBuilder 
      = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 
    requestBuilder.addTarget(imageReader.getSurface()); 
     cameraDevice.createCaptureSession(Collections.singletonList(imageReader.getSurface()), 
      new CameraCaptureSession.StateCallback() { 

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

        captureSession = cameraCaptureSession; 
        try { 
         requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, 
           CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); 
         requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF); 
         requestBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 1L); 

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

          @Override 
          public void onCaptureCompleted(@NonNull CameraCaptureSession session, 
            @NonNull CaptureRequest request, 
            @NonNull TotalCaptureResult result) { 
          } 
         }; 

         captureSession.setRepeatingRequest(
           requestBuilder.build(), captureCallback, callbackHandler); 
        } catch (CameraAccessException e) { 
         e.printStackTrace(); 
        } 
       } 

       @Override 
       public void onConfigureFailed(
         @NonNull CameraCaptureSession cameraCaptureSession) { 
       } 
      }, null); 
} catch (CameraAccessException e) { 
    e.printStackTrace(); 
} 

回答

1

首先,在SENSOR_FRAME_DURATION單位是在納秒,根據the docs

因此,與requestBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 1000000L);

另外嘗試,你可以不那麼優雅地使用CountDownTimer,並採取了做每1秒拍攝一張照片。我知道這很糟糕,因爲你每秒鐘都在初始化所有相機的東西,但這是一個正常工作的解決方案。一個例子是:

new CountDownTimer(5000,1000){ 
    @Override 
    public void onFinish() { (...) } 

    @Override 
    public void onTick(long millisUntilFinished) { 
     // TODO take picture 
    } 
}.start(); 

另一個第三解決方案將是使用Camera.Parameters [setPreviewFpsRange](https://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPreviewFpsRange(int,INT)),但它需要相機API而不是Camera2。但這只是另一種可能性

+0

不幸的是,setPreviewFpsRange()不會讓它更容易,因爲你只能選擇一個支持的範圍。大多數設備不會將1 fps列爲支持的幀速率。 –

+0

@AlexCohn你是完全正確的。但正確使用SENSOR_FRAME_DURATION的簡單方法必須做到訣竅 – webo80

+0

不一定。我不確定[SENSOR_INFO_MAX_FRAME_DURATION](https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#SENSOR_INFO_MAX_FRAME_DURATION)會說明什麼。對於全功能設備,保證至少100ms,但對其他設備沒有保證,甚至可能是** null **。 –

1

您控制onCaptureCompleted()被調用的頻率是有限的。但是你完全可以控制你在回調中做什麼。

如果您的相機產生20 fps,則可以跳過19個回調並捕獲第20個。如果您不確定幀速率是否足夠穩定,則可以爲所用的最後一張照片保留時間戳(使用SystemClock.elapsedRealtime()),並且忽略所有回調,直到此後一秒鐘。你甚至可以玩sleep()提高精度,如果你真的需要它。

相關問題