2017-04-19 1 views
0

Je travaille sur une application appareil photo Android qui doit utiliser une mise au point fixe (manuelle), et utilise toujours le flash. J'ai quelques problèmes qui semblent être avec le timing flash. Le flash se déclenche toujours et une image est toujours acquise, mais parfois le flash n'illumine pas réellement l'image capturée. Certaines images ont un flash, d'autres sont surexposées et certaines sont sombres; Fondamentalement, il est incohérent et imprévisible. J'ai basé mon code sur l'exemple Camera2Basic. Je pense que je l'ai montré toutes les parties concernées ici:Android Camera2 Flash Timing Problèmes

Mon constructeur de demande de prévisualisation a la configuration suivante

mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF); 
float minimumLens = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE); 
mPreviewRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, minimumLens); 
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_OFF); 
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH); 
mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF); 

Ensuite, la séquence réelle qui acquiert les images (presque tout droit de Camera2Basic) est la suivante:

private void takePicture() { 
    runPrecaptureSequence(); 
} 

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

    private void process(CaptureResult result) { 
     switch (mState) { 
      case STATE_PREVIEW: { 
       break; 
      } 
      case STATE_WAITING_PRECAPTURE: { 
       Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); 
       if (aeState == null || 
         aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE || 
         aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) { 
        mState = STATE_CAPTURE; 
       } 
       break; 
      } 

      case STATE_CAPTURE: { 
       // CONTROL_AE_STATE can be null on some devices 
       Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); 
       if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) { 
        mState = STATE_PICTURE_TAKEN; 
        captureStillPicture(); 
       } 
       break; 
      } 
     } 
    } 

    @Override 
    public void onCaptureProgressed(**ARGS**) { 
     process(partialResult); 
    } 

    @Override 
    public void onCaptureCompleted(**ARGS**) { 
     process(result); 
    } 

}; 

private void runPrecaptureSequence() { 
    try {   mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); 
     mState = STATE_WAITING_PRECAPTURE; 
     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; 
     } 

     final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); 
     captureBuilder.addTarget(mImageReader.getSurface()); 
     captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);   CaptureBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_OFF); 
     float minimumLens = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE); 
     captureBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, minimumLens); 
     captureBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH); 
     captureBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF); 
     int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); 
     captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation)); 

     mFileName = getFileNameFromTime() + ".jpg"; 

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

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

     mCaptureSession.stopRepeating(); 
     mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null); 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
} 

L'enregistrement de l'image a lieu dans l'appel ImageReader onImageAvailableListener et fonctionne correctement.

Il semble que le flash se déclenche avant que l'image ne soit acquise, donc j'ai essayé la suggestion dans this answer, mais le conditionnel FLASH_FIRED n'a jamais été déclenché.

Est-ce que quelqu'un avec une meilleure connaissance de Camera2 que moi peut voir où je suis en train de bousiller?

Répondre

-1

Ajoutez les trois lignes suivantes à l'échantillon Camera2Basic:

mPreviewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF); 
mPreviewRequestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, 4000); 
mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, FLASH_MODE_TORCH); 

Lorsque le flash est activé et un repeatingRequest est démarré, les réglages manuels sont remplacés par une sorte de paramétrage par défaut (capteur Sensibilité: 100). Mais la demande indique clairement capteur-sensibilité doit être 4000. Je l'ai testé avec ces deux lignes dans la méthode onCaptureCompleted:

Log.d(TAG, "request: "+request.get(CaptureRequest.SENSOR_SENSITIVITY)); 
Log.d(TAG, "result: "+result.get(CaptureResult.SENSOR_SENSITIVITY)); 
+0

Je n'ai pas eu la chance de tester encore, mais que la correction de la date de le flash par rapport au snap, ou juste en rendant l'exposition statique? – jranalli

+0

Donc, cette solution laisse le flash sur 100% du temps, ce qui n'est pas ce dont j'ai besoin. Je voudrais toujours l'avoir flash un seul, mais juste le temps le flash correctement. – jranalli