2015-05-12 16 views
11

Sto cercando di ottenere la cornice della fotocamera in modalità anteprima. Sto eseguendo il progetto di esempio da github https://github.com/googlesamples/android-Camera2BasicAndroid Camera2 getPreviewFrame

Il problema che sto avendo sta ottenendo il frame in modalità anteprima.

Ecco il codice:

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

    private void process(CaptureResult result) { 
     switch (mState) { 
      case STATE_PREVIEW: { 

       //HERE, HOW CAN I RETRIEVE THE CURRENT FRAME? 

       break; 
      } 
      case STATE_WAITING_LOCK: { 
       ... 
       break; 
      } 
      case STATE_WAITING_PRECAPTURE: { 
      ... 
       break; 
      } 
      case STATE_WAITING_NON_PRECAPTURE: { 
      ... 
       break; 
      } 
     } 
    } 

Un'altra cosa che ho cercato di ottenere il telaio è l'impostazione del mImageReader.setOnImageAvailableListener. Mi aspettavo di essere in grado di ottenere il frame sul callback ImageDisponibile, ma onImageAvailable non viene mai chiamato. onPreviewFrame è il mio metodo, ho bisogno di passarlo il frame corrente.

mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), ImageFormat.JPEG, /*maxImages*/2); 
    mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler); 

    private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() { 

    @Override 
    public void onImageAvailable(ImageReader reader) { 
     mTextureView.onPreviewFrame(reader.acquireNextImage().getPlanes([0].getBuffer().array()); 
    } 

}; 

Cosa sto facendo male? Grazie.

risposta

9

Il OnImageAvailableListener.onImageAvailable richiamata viene mai chiamato quando un frame di anteprima è disponibile perché il CaptureRequest che è stato inviato al metodo CameraCaptureSession.setRepeatingRequest() non ha lista 's la ImageReaderSurface come bersaglio di un output.

Si identifica l'uscita Surface s (buffer di byte non elaborati, in sostanza) in cui si desidera che i dati di ciascuna cattura vengano inviati quando si invia la richiesta alla telecamera. Quindi, per ottenere il "frame anteprima" per innescare la onImageAvailable() richiamata e poi essere inviato al tuo metodo di onPreviewFrame(), è sufficiente aggiungere la riga:.

mPreviewRequestBuilder.addTarget(mImageReader.getSurface());

Questa linea può andare, esempio, dopo l'altra simile linea che aggiunge lo allo stesso generatore di richieste.

Nota che questo invierà ogni fotogramma di anteprima alla tua funzione, così come i "fotogrammi di uscita" dal pulsante di acquisizione. Potresti volere del codice nel callback onImageAvailable() per discriminare.

+0

Ciao @Summer, conosci qualche metodo in cui posso utilizzare il frame sul metodo di elaborazione? grazie. –

+1

Intendi il metodo process() in mCaptureCallback? La risposta è no, l'unica cosa che viene inviata è i metadati di CaptureResult SULL'immagine. L'immagine stessa viene inviata ovunque tu abbia aggiunto come target alla corrispondente CaptureRequest. Ma fondamentalmente la domanda originale sopra è essenzialmente ciò che speri di fare, penso ... registrare un Surface di ImageReader come output di una richiesta e poi ascoltare che gli output appaiano con un OnImageAvailableListener(). – rcsumner

+0

Sfortunatamente, ho anche un problema simile e non sono riuscito a risolverlo con la risposta di cui sopra. Devo creare una nuova CaptureRequest? (nel campione ce n'è uno per l'anteprima, posso riutilizzarlo e aggiungere solo il target ad esso? – user2924714

Problemi correlati