2015-08-05 11 views
6

Sto utilizzando l'API Camera2 di Android e attualmente desidero che la fotocamera esegua una determinata azione ogni volta che si prepara a lampeggiare.Android: come rilevare se la fotocamera lampeggiava

Quando si costruisce il CaptureRequest, la riga seguente:

captureRequest.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); 

permette alla telecamera di flash in condizioni di scarsa illuminazione. Tuttavia, sono in perdita su come posso rilevare se la fotocamera è pronta a lampeggiare o meno. Sembra che la letteratura online su questa particolare azione sia piuttosto scarsa.

ho cercato controllando se FLASH_STATE è in FLASH_STATE_READY durante l'elaborazione di un partialresult nella fotocamera del CaptureCallback, ma sembra che la chiave non era disponibile - si continuava a tornare null. Forse non sto controllando nel posto giusto?

del CaptureCallback fotocamera, mostrato di seguito (in base al largo campione Camera2Basic il codice di Google):

private CameraCaptureSession.CaptureCallback mCaptureCallback 
     = new CameraCaptureSession.CaptureCallback() { 
    private void process(CaptureResult result) { 
     switch(mState) { 
      case STATE_PREVIEW: break; 
      case STATE_WAITING_LOCK: 
       // checking if result.get(CaptureResult.FLASH_STATE) == 
       // CaptureResult.FLASH_READY over here didn't work because 
       // null was returned 
       int afState = result.get(CaptureResult.CONTROL_AF_STATE); 
       if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState || 
         CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) { 
        Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); 
        if (aeState == null || 
          aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) { 
         mState = STATE_WAITING_NON_PRECAPTURE; 
         captureStillPicture(); 
        } else { 
         runPrecaptureSequence(); 
        } 
       } 
       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_WAITING_NON_PRECAPTURE; 
       } 
       break; 
      case STATE_WAITING_NON_PRECAPTURE: 
       Integer aeState1 = result.get(CaptureResult.CONTROL_AE_STATE); 
       if (aeState1 == null || aeState1 != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) { 
        mState = STATE_PICTURE_TAKEN; 
        captureStillPicture(); 
       } 
       break; 
     } 
    } 

    @Override 
    public void onCaptureProgressed(CameraCaptureSession session, 
            CaptureRequest request, CaptureResult partialResult) { 
     super.onCaptureProgressed(session, request, partialResult); 
     process(partialResult); 
    } 

    @Override 
    public void onCaptureCompleted(CameraCaptureSession session, 
            CaptureRequest request, TotalCaptureResult result) { 
     super.onCaptureCompleted(session, request, result); 
     process(result); 
    } 
}; 
+0

Controllare seguente classe per Flash in Camera2 API, http://stackoverflow.com/questions/27420594/android-5-camera2-use-only-flash/31289731#31289731 –

+0

Per leggere lo stato flash, attendere il risultato della cattura totale invece e controlla lo stato del flash lì; i partial potrebbero non avere ancora tutti i campi (in genere hanno i campi necessari per terminare l'AF, ecc. per la velocità). –

risposta

4

Nel documentation si può leggere la seguente dichiarazione per la chiave FLASH_STATE:

opzionale - Questo valore potrebbe essere nullo su alcuni dispositivi.

Fondamentalmente, anche se si utilizza un dispositivo Lollipop, non è possibile garantire che tutte le funzioni di Camera2 APi siano supportate. I dispositivi con funzioni limitate sono chiamati "dispositivi limitati".

Per maggiori informazioni dare un'occhiata alla pagina this. Questo lo descrive abbastanza bene.

EDIT: Per rispondere il commento che è fondamentalmente sbagliato: Le documentazioni dicono:

Quando il dispositivo fotocamera non dispone di flash (cioè android.flash.info.available == falso), questo stato sarà sempre NON DISPONIBILE. Altri stati indicano lo stato attuale del flash.

Quindi, se non c'è il flash sul dispositivo del FLASH_STATE è anche presente e tornerà UNAVAILABLE.

La documentazione dice praticamente tutto quello che devi sapere. Il fatto più importante è che dipende dalla modalità hardware/hardware.


Lets riassumere

Per dispositivi legacy

Si restituirà il seguente

  • licenziato se la modalità AE è impostato su ON_ALWAYS_FLASH
  • licenziato se il flash la modalità è impostata su TORCIA
  • NON DISPONIBILE se la fotocamera non ha flash.

Quando il dispositivo è almeno LEVEL_LIMITED:

Questi valori sono possibili, ma non v'è alcuna garanzia che tutto il lavoro:

  • UNAVAILABLE
  • CARICA
  • READY
  • FIRMATO
  • PARZIALE
+0

Grazie per la risposta rapida e le risorse. Quindi suppongo che una soluzione sia implementare il controllo della chiave 'FLASH_STATE' e usarla per quei dispositivi che la supportano, ma se il dispositivo non la supporta, è ancora possibile controllare in qualche altro modo? – rfblue2

+1

Hai ragione, il solito modo è controllare i valori che stai richiedendo. Non sono sicuro che ci sia un altro modo, ma credo di no. Perché lo stesso produttore di smartphone deve implementare un livello di astensione hardware per supportare le funzioni della camera2 api. Quindi suppongo che se non è possibile richiedere lo STATO in questo modo, l'interfaccia di comunicazione tra l'hardware e il programma manca per questa funzione. – FlanschiFox

+0

FLASH_STATE sarà presente se il dispositivo ha un'unità flash. –

0

Problema

Si sta tentando di rilevare se l'immagine scattata da vostra applicazione utilizza il flash o meno.

Soluzione

È possibile utilizzare Camera.Parameters per verificare lo stato del flash durante l'utilizzo della fotocamera se Flash è AUTO, ON o OFF.

Codice

È possibile utilizzare il seguente codice di esempio al fine di verificare lo stato del flash per la fotocamera.

Camera.Parameters p = mCamera.getParameters(); 

if(p.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_ON)) 
{ 
//DO STUFF 
} 
else if(p.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_OFF)) 
{ 
//DO STUFF 
} 
else if(p.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_TORCH)) 
{ 
//DO STUFF 
} 
else if(p.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_AUTO)) 
{ 
//DO STUFF 
} 
else 
{ 
//DO STUFF 
} 
+1

Camera.Parameters è obsoleto da API 21. È una buona idea utilizzarlo in combinazione con Camera API2? – FlanschiFox

+0

Grazie per la risposta rapida - domanda però - se la fotocamera è impostata su AUTO, come posso controllare se la fotocamera sta effettivamente per lampeggiare? Perché a volte in AUTO lampeggia e altre volte no. – rfblue2

+0

@ rfblue2 In caso di AUTO, è necessario controllare il FLASH_STATE che viene attivato dopo aver catturato l'immagine. Spero che questo ti aiuti. Potresti voler fare riferimento a questa documentazione ufficiale prima di iniziare a scrivere il codice: https://developer.android.com/reference/android/hardware/camera2/CaptureResult.html#FLASH_STATE –

0

API della fotocamera non è deprecato, seguente frammento di codice da Camera2 API per controllare il flash è disponibile o meno,

CameraManager mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); 
//here to judge if flash is available 

CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics("0"); 
boolean flashAvailable = cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE); 
if (flashAvailable) { 
     mCameraManager.openCamera("0", new MyCameraDeviceStateCallback(), null); 
} else { 
     //todo: throw Exception 
} 
+0

Cosa succede? Perché il punto negativo? Non funziona o cosa? –

+0

Grazie per la rapida risposta. Non sto cercando se la fotocamera abbia o meno il flash (a cui è stata data risposta in altre domande), ma piuttosto se il flash sta per sparare quando è impostato su AUTO flash, perché in modalità AUTO, il flash a volte spara e talvolta non è – rfblue2

0

Non c'è modo corrente per sapere con certezza se il flash scatta - la la decisione viene presa dal dispositivo della fotocamera all'ultimo momento prima della cattura a piena risoluzione. Una volta che il risultato finale dell'acquisizione per l'acquisizione a piena risoluzione è disponibile, il suo flash state dovrebbe essere FIRED se il flash ha sparato, ma lo otterrete dopo il fatto. Assicurati di attendere il risultato di acquisizione totale da onCaptureCompleted per verificare questo campo, non parziale da onCaptureProgressed; i risultati parziali possono mancare di vari campi.

Detto questo, se il AE state field prima di iniziare la sequenza prima della cattura è FLASH_REQUIRED, è molto probabile che il flash sarà licenziato se la modalità AE permette di flash (AE_MODE_ON_AUTO_FLASH/ALWAYS_FLASH/AUTO_FLASH_REDEYE).Non è una garanzia al 100%, dal momento che la scena può cambiare nei pochi fotogrammi tra l'inizio della sequenza di precapture (che eseguirà un flash di pre-ripresa per stimare la potenza flash necessaria) e l'effettiva acquisizione dell'immagine finale. Ma sospetto che il 95% delle volte sarà il risultato finale.

+0

Sembra promettente, ma anche CONTROL_AE_STATE è opzionale! (Ad esempio, se si controlla la documentazione, si dice 'Opzionale - Questo valore potrebbe essere nullo su alcuni dispositivi.). Questo è vero sul mio particolare dispositivo, che emette sempre "null". Immagino che l'unico controllo garantito per il flash sia dopo che è già successo? – rfblue2

+1

Il dispositivo è un dispositivo di livello LEGACY? Se è così, sì, allora non c'è molto da rivelare quell'informazione. I dispositivi LEGACY stanno eseguendo efficacemente l'API camera2 sulla vecchia API, a causa della mancanza di supporto hardware diretto, quindi sono abbastanza limitati nelle informazioni che possono produrre. Si noti che 'opzionale' non significa che sia completamente arbitrario sul fatto che il campo sia presente. Significa che esistono configurazioni in cui non è presente, quindi è necessario prestare attenzione, ma la maggior parte delle voci ha requisiti di esistenza ben definiti. AE_STATE deve essere presente su dispositivi LIMITATI o superiori. –

Problemi correlati