2017-04-13 2 views
0

J'essaie d'obtenir le cadre de la caméra en mode aperçu du projet échantillon Camera2 sur github https://github.com/googlesamples/android-Camera2BasicAndroid Camera2 image aperçu nulle

Ceci est similaire à cette question Android Camera2 getPreviewFrame

Mais, je suis courir dans 2 problèmes différents que je ne peux pas résoudre et n'ont pas été abordés dans la question précédente.

Premier problème: Dans la méthode onImageAvailable, reader.acquireNextImage() renvoie une image null.

Deuxième problème: l'ajout de mPreviewRequestBuilder.addTarget (mImageReader.getSurface()) ralentit considérablement l'aperçu de la caméra.

J'ai ajouté cette ligne

mPreviewRequestBuilder.addTarget(mImageReader.getSurface()); 

dans createCameraPreviewSession() sous laquelle il ajoute la surface à la même previewRequestBuilder.

Et voici ma méthode onImageAvailable

@Override 
public void onImageAvailable(ImageReader reader) { 
    try { 
     image = reader.acquireLatestImage(); 
     ByteBuffer buffer = image.getPlanes()[0].getBuffer(); 
     // use byte buffer for processing 
    } finally { 
     if (image != null) { 
      image.close(); 
     } 
     // make sure to close image 
    } 
} 

Répondre

0

Utilisez cette méthode createCameraPreviewSession(). Assurez-vous de faire les déclarations nécessaires. Sinon, vous pouvez trouver des erreurs.

private AutoFitTextureView mTextureView; 
private Size mPreviewSize; 
private CaptureRequest.Builder mPreviewRequestBuilder; 
private CaptureRequest mPreviewRequest; 
private CameraDevice mCameraDevice; 
private ImageReader mImageReader; 
private CameraCaptureSession mCaptureSession; 
private Handler mBackgroundHandler; 
private int mState = STATE_PREVIEW; 
private static final int STATE_PREVIEW = 0; 
private static final int STATE_WAITING_LOCK = 1; 
private static final int STATE_WAITING_PRECAPTURE = 2; 
private static final int STATE_WAITING_NON_PRECAPTURE = 3; 
private static final int STATE_PICTURE_TAKEN = 4; 


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

     // We configure the size of default buffer to be the size of camera preview we want. 
     texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); 

     // This is the output Surface we need to start preview. 
     Surface surface = new Surface(texture); 

     // We set up a CaptureRequest.Builder with the output Surface. 
     mPreviewRequestBuilder 
       = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 
     mPreviewRequestBuilder.addTarget(surface); 

     // Here, we create a CameraCaptureSession for camera preview. 
     mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()), 
       new CameraCaptureSession.StateCallback() { 

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

         // When the session is ready, we start displaying the preview. 
         mCaptureSession = cameraCaptureSession; 
         try { 
          // Auto focus should be continuous for camera preview. 
          mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, 
            CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); 
          // Flash is automatically enabled when necessary. 
          setAutoFlash(mPreviewRequestBuilder); 

          // Finally, we start displaying the camera preview. 
          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(); 
    } 
} 

Ceci est la méthode setAutoFlash, inclus dans le procédé ci-dessus:

private void setAutoFlash(CaptureRequest.Builder requestBuilder) { 
    if (mFlashSupported) { 
     requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, 
       CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); 
    } 
} 

Ceci est le mCaptureCallback utilisé dans createCameraPreviewSession() procédé:

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

    private void process(CaptureResult result) { 
     switch (mState) { 
      case STATE_PREVIEW: { 
       // We have nothing to do when the camera preview is working normally. 
       break; 
      } 
      case STATE_WAITING_LOCK: { 
       Integer afState = result.get(CaptureResult.CONTROL_AF_STATE); 
       if (afState == null) { 
        captureStillPicture(); 
       } else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState || 
         CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) { 
        // 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_CONVERGED) { 
         mState = STATE_PICTURE_TAKEN; 
         captureStillPicture(); 
        } else { 
         runPrecaptureSequence(); 
        } 
       } 
       break; 
      } 
      case STATE_WAITING_PRECAPTURE: { 
       // 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 || 
         aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) { 
        mState = STATE_WAITING_NON_PRECAPTURE; 
       } 
       break; 
      } 
      case STATE_WAITING_NON_PRECAPTURE: { 
       // 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(@NonNull CameraCaptureSession session, 
            @NonNull CaptureRequest request, 
            @NonNull CaptureResult partialResult) { 
     process(partialResult); 
    } 

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

};