Il framework Android include il supporto di varie fotocamere e funzionalità disponibili su per acquisire immagini e video nelle tue applicazioni. Il presente documento tratta di un approccio semplice e veloce all'acquisizione di immagini e video e delinea un approccio avanzato per la creazione esperienze con la videocamera personalizzate per i tuoi utenti.
Nota:
In questa pagina vengono descritti i
Camera
che è stata ritirata. Ti consigliamo di utilizzare
CameraX Jetpack o, per casi d'uso specifici,
camera2
,
. Sia CameraX che Camera2 funzionano su Android 5.0 (livello API 21) e
in alto.
Consulta le seguenti risorse correlate:
Considerazioni
Prima di consentire alla tua applicazione di utilizzare le fotocamere sui dispositivi Android, considera alcune domande sulla modalità di utilizzo di questa funzionalità hardware da parte dell'app.
- Requisito della fotocamera: l'uso di una videocamera è così importante per la tua un'applicazione per cui non desideri sia installata la tua applicazione su un dispositivo che non dispone di fotocamera? In questo caso, devi dichiarare il requisito della videocamera nel tuo del file manifest.
- Immagine rapida o fotocamera personalizzata: in che modo l'applicazione utilizzerà fotocamera? Ti interessa solo scattare una foto o un video clip o la tua applicazione offrono un nuovo modo di utilizzare le videocamere? Per ottenere uno scatto o una clip veloci, Utilizzare le app Fotocamera esistenti. Per sviluppare una funzionalità personalizzata della fotocamera, controlla consulta la sezione Creazione di un'app fotocamera.
- Requisito per i servizi in primo piano: quando interagisce la tua app con la fotocamera? Su Android 9 (livello API 28) e versioni successive, le app in esecuzione nel lo sfondo non può accedere alla fotocamera. Per questo motivo, devi usare la videocamera quando la tua app è in primo piano o nell'ambito di un servizio in primo piano.
- Archiviazione: le immagini o i video generati dall'applicazione sono destinati visibile solo alla tua applicazione o condivisa in modo che altre applicazioni, come Galleria o altre media e social possono utilizzarle? Vuoi che le immagini e i video siano disponibili anche se le tue disinstallata? Consulta la sezione Salvataggio di file multimediali per scopri come implementare queste opzioni.
Nozioni di base
Il framework Android supporta l'acquisizione di immagini e video tramite
android.hardware.camera2
API o fotocamera Intent
. Ecco le informazioni pertinenti
classi:
android.hardware.camera2
- Questo pacchetto è l'API principale per il controllo delle fotocamere dei dispositivi. Può essere usato per immagini o video quando crei un'applicazione per la fotocamera.
Camera
- Questa classe è l'API obsoleta per controllare le fotocamere dei dispositivi.
SurfaceView
- Questo corso viene utilizzato per presentare all'utente un'anteprima in diretta della fotocamera.
MediaRecorder
- Questo corso viene utilizzato per registrare video dalla videocamera.
Intent
- È possibile utilizzare un tipo di azione intent
MediaStore.ACTION_IMAGE_CAPTURE
oMediaStore.ACTION_VIDEO_CAPTURE
per acquisire immagini o video senza dover utilizzando l'oggettoCamera
.
Dichiarazioni del file manifest
Prima di iniziare a sviluppare la tua applicazione con l'API Camera, devi assicurarti il file manifest contenga le dichiarazioni appropriate per consentire l'uso di hardware della videocamera e di altri funzionalità correlate.
- Autorizzazione Fotocamera. L'applicazione deve richiedere l'autorizzazione a utilizzare un dispositivo.
fotocamera.
<uses-permission android:name="android.permission.CAMERA" />
Nota: se utilizzi la fotocamera by richiamando un'app fotocamera esistente, l'applicazione non deve richiedere questa autorizzazione.
- Funzionalità della fotocamera. L'applicazione deve inoltre dichiarare l'utilizzo delle funzionalità della fotocamera,
Ad esempio:
<uses-feature android:name="android.hardware.camera" />
Per un elenco delle funzionalità della fotocamera, consulta il file manifest Funzionalità Riferimento.
Se aggiungi funzionalità della videocamera al file manifest, Google Play impedisce alla tua applicazione di l'installazione su dispositivi che non includono una videocamera o che non supportano le relative funzionalità specificare. Per ulteriori informazioni sull'utilizzo dei filtri basati sulle funzionalità con Google Play, consulta Google Play e filtri basati sulle funzionalità.
Se la tua applicazione può utilizzare una fotocamera o una funzionalità della fotocamera per il corretto funzionamento, ma non è obbligatorio, devi specificarlo nel file manifest includendo l'attributo
android:required
e impostandolo sufalse
:<uses-feature android:name="android.hardware.camera" android:required="false" />
- Autorizzazione spazio di archiviazione. La tua applicazione può salvare immagini o video nel
alla memoria esterna (scheda SD) del dispositivo se ha come target Android 10 (livello API 29) oppure
e specifica quanto segue nel manifest.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- Autorizzazione registrazione audio: per registrare audio con l'acquisizione video,
deve richiedere l'autorizzazione di acquisizione dell'audio.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
-
Autorizzazione di accesso alla posizione: se la tua applicazione tagga le immagini con le informazioni sulla posizione GPS, devi richiedere
ACCESS_FINE_LOCATION
autorizzazione. Tieni presente che, se la tua app ha come target Android 5.0 (livello API 21) oppure superiore, devi anche dichiarare che l'app utilizza il GPS del dispositivo:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ... <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. --> <uses-feature android:name="android.hardware.location.gps" />
Per ulteriori informazioni su come ottenere la posizione dell'utente, vedi Strategie per le località.
Usare app della fotocamera esistenti
Un modo rapido per scattare foto o registrare video nella tua applicazione senza molto codice aggiuntivo
consiste nell'utilizzare un Intent
per richiamare un'applicazione della fotocamera Android esistente.
I dettagli sono descritti nelle lezioni di formazione
Scattare foto in modo semplice e
Registrare video in modo semplice.
Creazione di un'app fotocamera
Alcuni sviluppatori potrebbero richiedere un'interfaccia utente della fotocamera personalizzata per l'aspetto un'applicazione o offre funzionalità speciali. Scrivere codice personalizzato per scattare foto può offrire un'esperienza più accattivante agli utenti.
Nota: la seguente guida si riferisce alla versione precedente di Camera
, deprecata
tramite Google Cloud CLI
o tramite l'API Compute Engine. Per le applicazioni di fotocamera nuove o avanzate, la versione più recente dell'API android.hardware.camera2
è
consigliati.
Di seguito sono riportati i passaggi generali per la creazione di un'interfaccia della videocamera personalizzata per la tua applicazione:
- Rileva e accedi alla videocamera. Crea un codice per verificare l'esistenza di videocamere e richiedere l'accesso.
- Crea un corso in anteprima: crea una classe di anteprima della fotocamera che estende
SurfaceView
e implementa l'interfacciaSurfaceHolder
. Questo di classe mostra l'anteprima delle immagini in diretta della fotocamera. - Crea un layout di anteprima: dopo aver ottenuto il corso di anteprima della fotocamera, crea un che include l'anteprima e i controlli dell'interfaccia utente desiderati.
- Configura i listener per l'acquisizione: collega i listener per la tua interfaccia. per avviare l'acquisizione di immagini o video in risposta alle azioni dell'utente, ad esempio la pressione di un .
- Acquisisci e salva file: configura il codice per acquisire le immagini o video e salvare l'output.
- Rilascia la fotocamera. Dopo aver utilizzato la fotocamera, l'applicazione deve: correttamente rilasciarlo per l'uso da parte di altre applicazioni.
L'hardware della videocamera è una risorsa condivisa che deve essere gestita con attenzione affinché l'applicazione non in conflitto con altre applicazioni che potrebbero volerla utilizzare. Le sezioni seguenti trattano come rilevare l'hardware di una videocamera, come richiedere l'accesso a una fotocamera, come acquisire foto o registrare video e su come rilasciare la fotocamera quando l'applicazione ha finito di utilizzarla.
Attenzione: ricorda di rilasciare Camera
richiamando Camera.release()
quando
l'applicazione usarla. Se l'applicazione non rilascia correttamente la fotocamera,
I tentativi successivi di accedere alla videocamera, inclusi quelli effettuati dalla tua applicazione, non andranno a buon fine e potrebbero
l'arresto della tua applicazione o di altre applicazioni.
Rilevamento dell'hardware della videocamera in corso...
Se la tua applicazione non richiede specificamente una videocamera con una dichiarazione del file manifest,
devi controllare se una videocamera è disponibile in fase di runtime. Per eseguire questo controllo, utilizza il metodo PackageManager.hasSystemFeature()
, come mostrato nel codice di esempio riportato di seguito:
Kotlin
/** Check if this device has a camera */ private fun checkCameraHardware(context: Context): Boolean { if (context.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { // this device has a camera return true } else { // no camera on this device return false } }
Java
/** Check if this device has a camera */ private boolean checkCameraHardware(Context context) { if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){ // this device has a camera return true; } else { // no camera on this device return false; } }
I dispositivi Android possono avere più fotocamere, ad esempio una fotocamera posteriore per la fotografia e una
fotocamera anteriore per le videochiamate. Android 2.3 (API Livello 9) e versioni successive ti consente di controllare
numero di videocamere disponibili su un dispositivo con il metodo Camera.getNumberOfCameras()
.
Accesso alle videocamere
Se hai stabilito che il dispositivo su cui è in esecuzione la tua applicazione è dotato di una fotocamera,
devi richiedere l'accesso ottenendo un'istanza di Camera
(a meno che tu
stai utilizzando un intent per accedere alla fotocamera).
Per accedere alla fotocamera principale, usa il metodo Camera.open()
e di rilevare eventuali eccezioni, come illustrato nel codice riportato di seguito:
Kotlin
/** A safe way to get an instance of the Camera object. */ fun getCameraInstance(): Camera? { return try { Camera.open() // attempt to get a Camera instance } catch (e: Exception) { // Camera is not available (in use or does not exist) null // returns null if camera is unavailable } }
Java
/** A safe way to get an instance of the Camera object. */ public static Camera getCameraInstance(){ Camera c = null; try { c = Camera.open(); // attempt to get a Camera instance } catch (Exception e){ // Camera is not available (in use or does not exist) } return c; // returns null if camera is unavailable }
Attenzione:verifica sempre la presenza di eccezioni quando utilizzi Camera.open()
. Mancata ricerca di eccezioni se la videocamera è in modalità
use o non esiste comporterà l'arresto dell'applicazione da parte del sistema.
Sui dispositivi con Android 2.3 (livello API 9) o versioni successive, puoi accedere a fotocamere specifiche utilizzando
Camera.open(int)
. Il codice di esempio riportato sopra consente di accedere
la prima fotocamera posteriore di un dispositivo con più di una fotocamera.
Controllo delle funzionalità della fotocamera in corso...
Una volta ottenuto l'accesso a una fotocamera, puoi ottenere ulteriori informazioni sulle sue funzionalità utilizzando
il metodo Camera.getParameters()
e controllare
ha restituito Camera.Parameters
per le funzionalità supportate. Quando si utilizza
API di livello 9 o superiore, utilizza Camera.getCameraInfo()
per determinare se una fotocamera si trova nella parte anteriore
o il retro del dispositivo e l'orientamento dell'immagine.
Creazione di un corso di anteprima
Per poter scattare foto o registrare video in modo efficace, gli utenti devono essere in grado di vedere la fotocamera del dispositivo
vede. Una classe di anteprima della fotocamera è un SurfaceView
che può visualizzare l'immagine live
Dati provenienti da una fotocamera, in modo che gli utenti possano inquadrare e acquisire una foto o un video.
Il seguente codice di esempio mostra come creare una classe di anteprima di base della fotocamera che può essere
incluso in un layout View
. Questa classe implementa SurfaceHolder.Callback
per acquisire gli eventi di callback
per creare ed eliminare la vista, necessarie per assegnare l'input di anteprima della videocamera.
Kotlin
/** A basic Camera preview class */ class CameraPreview( context: Context, private val mCamera: Camera ) : SurfaceView(context), SurfaceHolder.Callback { private val mHolder: SurfaceHolder = holder.apply { // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. addCallback(this@CameraPreview) // deprecated setting, but required on Android versions prior to 3.0 setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) } override fun surfaceCreated(holder: SurfaceHolder) { // The Surface has been created, now tell the camera where to draw the preview. mCamera.apply { try { setPreviewDisplay(holder) startPreview() } catch (e: IOException) { Log.d(TAG, "Error setting camera preview: ${e.message}") } } } override fun surfaceDestroyed(holder: SurfaceHolder) { // empty. Take care of releasing the Camera preview in your activity. } override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) { // If your preview can change or rotate, take care of those events here. // Make sure to stop the preview before resizing or reformatting it. if (mHolder.surface == null) { // preview surface does not exist return } // stop preview before making changes try { mCamera.stopPreview() } catch (e: Exception) { // ignore: tried to stop a non-existent preview } // set preview size and make any resize, rotate or // reformatting changes here // start preview with new settings mCamera.apply { try { setPreviewDisplay(mHolder) startPreview() } catch (e: Exception) { Log.d(TAG, "Error starting camera preview: ${e.message}") } } } }
Java
/** A basic Camera preview class */ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private Camera mCamera; public CameraPreview(Context context, Camera camera) { super(context); mCamera = camera; // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. mHolder = getHolder(); mHolder.addCallback(this); // deprecated setting, but required on Android versions prior to 3.0 mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void surfaceCreated(SurfaceHolder holder) { // The Surface has been created, now tell the camera where to draw the preview. try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } catch (IOException e) { Log.d(TAG, "Error setting camera preview: " + e.getMessage()); } } public void surfaceDestroyed(SurfaceHolder holder) { // empty. Take care of releasing the Camera preview in your activity. } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // If your preview can change or rotate, take care of those events here. // Make sure to stop the preview before resizing or reformatting it. if (mHolder.getSurface() == null){ // preview surface does not exist return; } // stop preview before making changes try { mCamera.stopPreview(); } catch (Exception e){ // ignore: tried to stop a non-existent preview } // set preview size and make any resize, rotate or // reformatting changes here // start preview with new settings try { mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); } catch (Exception e){ Log.d(TAG, "Error starting camera preview: " + e.getMessage()); } } }
Se vuoi impostare una dimensione specifica per l'anteprima della fotocamera, impostala nel metodo surfaceChanged()
, come indicato nei commenti sopra. Quando imposti le dimensioni di anteprima,
deve utilizzare valori di getSupportedPreviewSizes()
.
Non impostare valori arbitrari nel metodo setPreviewSize()
.
Nota:
Con l'introduzione del
Multi-finestra in Android 7.0 (livello API 24) e versioni successive, non
presupporremo più che le proporzioni dell'anteprima siano le stesse della tua attività
anche dopo aver chiamato setDisplayOrientation()
.
A seconda delle dimensioni e delle proporzioni della finestra, potrebbe essere necessario adattare
dell'anteprima della fotocamera in un layout con orientamento verticale o viceversa, utilizzando una
layout letterbox.
Inserire l'anteprima in un layout
Una classe di anteprima della fotocamera, come l'esempio mostrato nella sezione precedente, deve essere inserita nella layout di un'attività insieme ad altri controlli dell'interfaccia utente per scattare foto o registrare video. Questo mostra come creare un layout di base e un'attività per l'anteprima.
Il seguente codice di layout fornisce una visualizzazione molto basilare che può essere utilizzata per mostrare una videocamera
l'anteprima. In questo esempio, l'elemento FrameLayout
deve essere
contenitore per la classe di anteprima della fotocamera. Questo tipo di layout viene utilizzato per mostrare
informazioni o controlli possono essere sovrapposti alle immagini di anteprima della fotocamera in diretta.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" > <FrameLayout android:id="@+id/camera_preview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" /> <Button android:id="@+id/button_capture" android:text="Capture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> </LinearLayout>
Sulla maggior parte dei dispositivi, l'orientamento predefinito dell'anteprima della fotocamera è Orizzontale. Questo layout di esempio specifica un layout orizzontale e il codice seguente fissa l'orientamento del dall'applicazione all'orientamento orizzontale. Per semplicità nel rendering dell'anteprima di una fotocamera, devi modificare l'orientamento dell'attività di anteprima dell'applicazione in orizzontale aggiungendo quanto segue alla del file manifest.
<activity android:name=".CameraActivity" android:label="@string/app_name" android:screenOrientation="landscape"> <!-- configure this activity to use landscape orientation --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
Nota:l'anteprima della fotocamera non deve essere necessariamente in modalità Orizzontale.
A partire da Android 2.2 (livello API 8), puoi utilizzare il metodo setDisplayOrientation()
per impostare il valore
rotazione dell'immagine di anteprima. Per cambiare l'orientamento dell'anteprima quando l'utente orienta nuovamente la
telefono, nel metodo surfaceChanged()
del corso in anteprima, interrompi prima l'anteprima con Camera.stopPreview()
modifica l'orientamento, quindi
riavvia l'anteprima con Camera.startPreview()
.
Nell'attività per la visualizzazione della videocamera, aggiungi la classe di anteprima all'elemento FrameLayout
mostrato nell'esempio sopra. L'attività della videocamera deve inoltre
assicurati di rilasciare la videocamera quando è in pausa o si spegne. L'esempio seguente mostra come
per modificare un'attività della videocamera per allegare la lezione di anteprima mostrata in Creazione di
un corso in anteprima.
Kotlin
class CameraActivity : Activity() { private var mCamera: Camera? = null private var mPreview: CameraPreview? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Create an instance of Camera mCamera = getCameraInstance() mPreview = mCamera?.let { // Create our Preview view CameraPreview(this, it) } // Set the Preview view as the content of our activity. mPreview?.also { val preview: FrameLayout = findViewById(R.id.camera_preview) preview.addView(it) } } }
Java
public class CameraActivity extends Activity { private Camera mCamera; private CameraPreview mPreview; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Create an instance of Camera mCamera = getCameraInstance(); // Create our Preview view and set it as the content of our activity. mPreview = new CameraPreview(this, mCamera); FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); preview.addView(mPreview); } }
Nota: il metodo getCameraInstance()
nell'esempio precedente
si riferisce al metodo di esempio mostrato in Accedere alle videocamere.
Acquisizione di foto
Dopo aver creato un corso di anteprima e un layout di visualizzazione in cui mostrarlo, sei pronto a iniziare ad acquisire immagini con la tua applicazione. Nel codice dell'applicazione, devi impostare i listener per consentire ai controlli dell'interfaccia utente di rispondere a un'azione utente scattando una foto.
Per recuperare un'immagine, usa il metodo Camera.takePicture()
. Questo metodo prende tre parametri che ricevono i dati dalla videocamera.
Per ricevere dati in formato JPEG, devi implementare un'interfaccia Camera.PictureCallback
per ricevere i dati dell'immagine e
e scriverlo in un file. Il seguente codice mostra un'implementazione di base dell'interfaccia Camera.PictureCallback
per salvare un'immagine ricevuta dalla fotocamera.
Kotlin
private val mPicture = Camera.PictureCallback { data, _ -> val pictureFile: File = getOutputMediaFile(MEDIA_TYPE_IMAGE) ?: run { Log.d(TAG, ("Error creating media file, check storage permissions")) return@PictureCallback } try { val fos = FileOutputStream(pictureFile) fos.write(data) fos.close() } catch (e: FileNotFoundException) { Log.d(TAG, "File not found: ${e.message}") } catch (e: IOException) { Log.d(TAG, "Error accessing file: ${e.message}") } }
Java
private PictureCallback mPicture = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE); if (pictureFile == null){ Log.d(TAG, "Error creating media file, check storage permissions"); return; } try { FileOutputStream fos = new FileOutputStream(pictureFile); fos.write(data); fos.close(); } catch (FileNotFoundException e) { Log.d(TAG, "File not found: " + e.getMessage()); } catch (IOException e) { Log.d(TAG, "Error accessing file: " + e.getMessage()); } } };
Attiva l'acquisizione di un'immagine chiamando il metodo Camera.takePicture()
. Il codice di esempio riportato di seguito mostra come chiamare questo metodo da un
pulsante View.OnClickListener
.
Kotlin
val captureButton: Button = findViewById(R.id.button_capture) captureButton.setOnClickListener { // get an image from the camera mCamera?.takePicture(null, null, picture) }
Java
// Add a listener to the Capture button Button captureButton = (Button) findViewById(R.id.button_capture); captureButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { // get an image from the camera mCamera.takePicture(null, null, picture); } } );
Nota: il membro mPicture
nell'esempio seguente fa riferimento
al codice di esempio riportato sopra.
Attenzione: ricorda di rilasciare Camera
richiamando Camera.release()
quando
l'applicazione usarla. Per informazioni su come rilasciare la fotocamera, consulta l'articolo Rilascio della fotocamera.
Acquisizione dei video
L'acquisizione di video con il framework Android richiede una gestione accurata dell'oggetto Camera
e la coordinazione con MediaRecorder
. Quando registri video con Camera
, devi gestire le chiamate Camera.lock()
e Camera.unlock()
per consentire a MediaRecorder
di accedere all'hardware della videocamera.
oltre alle chiamate Camera.open()
e Camera.release()
.
Nota: a partire da Android 4.0 (livello API 14), le chiamate Camera.lock()
e Camera.unlock()
vengono gestite automaticamente.
A differenza di quanto accade per le foto con la fotocamera di un dispositivo, l'acquisizione di video richiede una chiamata molto particolare ordine. Devi seguire un ordine di esecuzione specifico per preparare e acquisire correttamente il video con la tua applicazione, come descritto di seguito.
- Apri Fotocamera. Usa l'
Camera.open()
per ottenere un'istanza dell'oggetto camera. - Collega anteprima: prepara un'anteprima in diretta dell'immagine della fotocamera collegando un
SurfaceView
alla fotocamera utilizzandoCamera.setPreviewDisplay()
. - Avvia anteprima - Chiama il numero
Camera.startPreview()
per iniziare a visualizzare le immagini in diretta della videocamera. - Avvia la registrazione del video: i seguenti passaggi devono essere completati in
per registrare correttamente il video:
- Sblocca la fotocamera. Sblocca la videocamera per utilizzarla entro il giorno
MediaRecorder
chiamando il numeroCamera.unlock()
. - Configura MediaRecorder: chiama i seguenti metodi
MediaRecorder
in questo ordine. Per saperne di più, consulta la documentazione di riferimento perMediaRecorder
.setCamera()
- Imposta la fotocamera da utilizzare per l'acquisizione video; usa l'istanza attuale della tua applicazione diCamera
.setAudioSource()
- Imposta il parametro usaMediaRecorder.AudioSource.CAMCORDER
.setVideoSource()
- Imposta l'origine video, utilizzaMediaRecorder.VideoSource.CAMERA
.- Imposta il formato di output video e la codifica. Per Android 2.2 (API Livello 8) e
in più, utilizza il metodo
MediaRecorder.setProfile
e ottieni un'istanza del profilo utilizzandoCamcorderProfile.get()
. Per le versioni di Android precedenti 2.2, devi impostare il formato di output del video e i parametri di codifica:setOutputFormat()
- Imposta il formato di output, specifica l'impostazione predefinita oMediaRecorder.OutputFormat.MPEG_4
.setAudioEncoder()
- Imposta il tipo di codifica audio, specifica l'impostazione predefinita oMediaRecorder.AudioEncoder.AMR_NB
.setVideoEncoder()
- Imposta il tipo di codifica video, specifica l'impostazione predefinita oMediaRecorder.VideoEncoder.MPEG_4_SP
.
setOutputFile()
- Imposta il file di output, utilizzagetOutputMediaFile(MEDIA_TYPE_VIDEO).toString()
dell'esempio nella sezione Salvataggio di file multimediali.setPreviewDisplay()
- Specifica l'elemento di layout di anteprimaSurfaceView
per la tua applicazione. Utilizza lo stesso oggetto che hai specificato per Connect Preview.
Attenzione:devi chiamare questi metodi di configurazione
MediaRecorder
in questo ordine, altrimenti i tuoi l'applicazione riscontrerà errori e la registrazione non andrà a buon fine. - Prepara MediaRecorder: prepara
MediaRecorder
con le impostazioni di configurazione fornite chiamandoMediaRecorder.prepare()
. - Avvia MediaRecorder: avvia la registrazione di video chiamando il numero
MediaRecorder.start()
.
- Sblocca la fotocamera. Sblocca la videocamera per utilizzarla entro il giorno
- Interrompi la registrazione del video. Chiama i seguenti metodi in ordine, per
completare correttamente una registrazione video:
- Interrompi MediaRecorder: interrompi la registrazione del video chiamando il numero
MediaRecorder.stop()
. - Reimposta MediaRecorder: se vuoi, rimuovi le impostazioni di configurazione da
il registratore chiamando
MediaRecorder.reset()
. - Rilascia MediaRecorder. Rilascia
MediaRecorder
chiamando il numeroMediaRecorder.release()
. - Blocca la videocamera: blocca la videocamera in modo che le future sessioni
MediaRecorder
possano utilizzarla chiamando il numeroCamera.lock()
. A partire da Android 4.0 (livello API 14), questa chiamata non è necessaria, a meno che non venga ChiamataMediaRecorder.prepare()
non riuscita.
- Interrompi MediaRecorder: interrompi la registrazione del video chiamando il numero
- Interrompi l'anteprima: al termine dell'attività di utilizzo della fotocamera, interrompi
utilizzando
Camera.stopPreview()
. - Rilascia fotocamera: rilascia la fotocamera per consentire ad altre applicazioni di utilizzarla.
chiamando
Camera.release()
.
Nota: è possibile utilizzare MediaRecorder
senza creare prima un'anteprima della videocamera e salta i primi passaggi di questa procedura. Tuttavia,
poiché gli utenti preferiscono vedere un'anteprima prima di avviare la registrazione, questo processo non
di cui parleremo qui.
Suggerimento: se la tua applicazione viene solitamente utilizzata per la registrazione di video, imposta
dal giorno setRecordingHint(boolean)
al giorno true
prima di iniziare
l'anteprima. Questa impostazione può aiutare a ridurre il tempo necessario per avviare la registrazione.
Configurazione di MediaRecorder
Se utilizzi la classe MediaRecorder
per registrare video, devi eseguire
passaggi di configurazione in un ordine specifico, quindi chiama il metodo MediaRecorder.prepare()
per verificare e implementare il
configurazione. Il seguente codice di esempio mostra come configurare e preparare correttamente il
MediaRecorder
corso per la registrazione video.
Kotlin
private fun prepareVideoRecorder(): Boolean { mediaRecorder = MediaRecorder() mCamera?.let { camera -> // Step 1: Unlock and set camera to MediaRecorder camera?.unlock() mediaRecorder?.run { setCamera(camera) // Step 2: Set sources setAudioSource(MediaRecorder.AudioSource.CAMCORDER) setVideoSource(MediaRecorder.VideoSource.CAMERA) // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)) // Step 4: Set output file setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()) // Step 5: Set the preview output setPreviewDisplay(mPreview?.holder?.surface) setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT) setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT) // Step 6: Prepare configured MediaRecorder return try { prepare() true } catch (e: IllegalStateException) { Log.d(TAG, "IllegalStateException preparing MediaRecorder: ${e.message}") releaseMediaRecorder() false } catch (e: IOException) { Log.d(TAG, "IOException preparing MediaRecorder: ${e.message}") releaseMediaRecorder() false } } } return false }
Java
private boolean prepareVideoRecorder(){ mCamera = getCameraInstance(); mediaRecorder = new MediaRecorder(); // Step 1: Unlock and set camera to MediaRecorder mCamera.unlock(); mediaRecorder.setCamera(mCamera); // Step 2: Set sources mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); // Step 4: Set output file mediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); // Step 5: Set the preview output mediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); // Step 6: Prepare configured MediaRecorder try { mediaRecorder.prepare(); } catch (IllegalStateException e) { Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } catch (IOException e) { Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } return true; }
Prima di Android 2.2 (livello API 8), devi impostare il formato di output e i formati di codifica
anziché utilizzare CamcorderProfile
. Questo approccio è
come illustrato nel seguente codice:
Kotlin
// Step 3: Set output format and encoding (for versions prior to API Level 8) mediaRecorder?.apply { setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT) setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT) }
Java
// Step 3: Set output format and encoding (for versions prior to API Level 8) mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
Sono stati forniti i seguenti parametri di registrazione video per MediaRecorder
impostazioni predefinite, tuttavia, ti consigliamo di modificare le seguenti impostazioni per la tua applicazione:
setVideoEncodingBitRate()
setVideoSize()
setVideoFrameRate()
setAudioEncodingBitRate()
setAudioChannels()
setAudioSamplingRate()
Avvio e interruzione di MediaRecorder
Quando avvii e interrompi la registrazione video utilizzando il corso MediaRecorder
,
devi seguire un ordine specifico, indicato di seguito.
- Sblocca la fotocamera con
Camera.unlock()
- Configura
MediaRecorder
come mostrato nel codice di esempio riportato sopra - Avvia la registrazione usando
MediaRecorder.start()
- Registra il video
- Interrompi la registrazione utilizzando
MediaRecorder.stop()
- Rilascia il registratore multimediale con
MediaRecorder.release()
- Blocca la fotocamera usando
Camera.lock()
Il seguente codice di esempio mostra come collegare un pulsante per avviare e arrestare correttamente
registrazione video utilizzando la fotocamera e la classe MediaRecorder
.
Nota: quando completi una registrazione video, non rilasciare la fotocamera altrimenti l'anteprima verrà interrotta.
Kotlin
var isRecording = false val captureButton: Button = findViewById(R.id.button_capture) captureButton.setOnClickListener { if (isRecording) { // stop recording and release camera mediaRecorder?.stop() // stop the recording releaseMediaRecorder() // release the MediaRecorder object mCamera?.lock() // take camera access back from MediaRecorder // inform the user that recording has stopped setCaptureButtonText("Capture") isRecording = false } else { // initialize video camera if (prepareVideoRecorder()) { // Camera is available and unlocked, MediaRecorder is prepared, // now you can start recording mediaRecorder?.start() // inform the user that recording has started setCaptureButtonText("Stop") isRecording = true } else { // prepare didn't work, release the camera releaseMediaRecorder() // inform user } } }
Java
private boolean isRecording = false; // Add a listener to the Capture button Button captureButton = (Button) findViewById(id.button_capture); captureButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { if (isRecording) { // stop recording and release camera mediaRecorder.stop(); // stop the recording releaseMediaRecorder(); // release the MediaRecorder object mCamera.lock(); // take camera access back from MediaRecorder // inform the user that recording has stopped setCaptureButtonText("Capture"); isRecording = false; } else { // initialize video camera if (prepareVideoRecorder()) { // Camera is available and unlocked, MediaRecorder is prepared, // now you can start recording mediaRecorder.start(); // inform the user that recording has started setCaptureButtonText("Stop"); isRecording = true; } else { // prepare didn't work, release the camera releaseMediaRecorder(); // inform user } } } } );
Nota: nell'esempio precedente, il campo prepareVideoRecorder()
fa riferimento al codice di esempio mostrato in Configurazione di MediaRecorder. Questo metodo consente di bloccare
la videocamera, configurando e preparando l'istanza MediaRecorder
.
Rilascio della fotocamera
Le videocamere sono una risorsa condivisa dalle applicazioni su un dispositivo. La tua applicazione può
l'utilizzo della videocamera dopo aver ricevuto un'istanza di Camera
e devi avere
particolarmente attento a rilasciare l'oggetto fotocamera quando l'applicazione smette di utilizzarlo e
non appena l'applicazione viene messa in pausa (Activity.onPause()
). Se
l'applicazione non rilascia correttamente la fotocamera, in tutti i tentativi successivi di accesso alla fotocamera
incluse quelle della tua applicazione, non riusciranno e potrebbero causare il
è stato arrestato.
Per rilasciare un'istanza dell'oggetto Camera
, utilizza il metodo Camera.release()
, come mostrato nel codice di esempio riportato di seguito.
Kotlin
class CameraActivity : Activity() { private var mCamera: Camera? private var preview: SurfaceView? private var mediaRecorder: MediaRecorder? override fun onPause() { super.onPause() releaseMediaRecorder() // if you are using MediaRecorder, release it first releaseCamera() // release the camera immediately on pause event } private fun releaseMediaRecorder() { mediaRecorder?.reset() // clear recorder configuration mediaRecorder?.release() // release the recorder object mediaRecorder = null mCamera?.lock() // lock camera for later use } private fun releaseCamera() { mCamera?.release() // release the camera for other applications mCamera = null } }
Java
public class CameraActivity extends Activity { private Camera mCamera; private SurfaceView preview; private MediaRecorder mediaRecorder; ... @Override protected void onPause() { super.onPause(); releaseMediaRecorder(); // if you are using MediaRecorder, release it first releaseCamera(); // release the camera immediately on pause event } private void releaseMediaRecorder(){ if (mediaRecorder != null) { mediaRecorder.reset(); // clear recorder configuration mediaRecorder.release(); // release the recorder object mediaRecorder = null; mCamera.lock(); // lock camera for later use } } private void releaseCamera(){ if (mCamera != null){ mCamera.release(); // release the camera for other applications mCamera = null; } } }
Attenzione:se l'applicazione non rilascia correttamente il videocamera, tutti i tentativi successivi di accesso alla videocamera, inclusi quelli effettuati dalla tua applicazione, potrebbero non funzionare e causare l'arresto dell'applicazione o di altre applicazioni.
Salvataggio dei file multimediali in corso...
I file multimediali creati dagli utenti, come immagini e video, devono essere salvati sull'esterno del dispositivo directory di archiviazione (scheda SD) per risparmiare spazio di sistema e consentire agli utenti di accedere a questi file senza il loro dispositivo. Esistono molte posizioni di directory in cui salvare i file multimediali su un dispositivo, tuttavia, come sviluppatore, devi prendere in considerazione solo due località standard:
Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES
): questo metodo restituisce lo standard, condiviso e consigliato posizione per salvare immagini e video. Questa directory è condivisa (pubblica), quindi altre applicazioni può facilmente scoprire, leggere, modificare ed eliminare i file salvati in questa posizione. Se la tua applicazione è disinstallati dall'utente, i file multimediali salvati in questa posizione non verranno rimossi. Da evitare che interferiscano con le foto e i video esistenti degli utenti, ti consigliamo di creare una sottodirectory per dell'applicazione all'interno di questa directory, come mostrato nell'esempio di codice riportato di seguito. Questo metodo è disponibile in Android 2.2 (livello API 8). Per le chiamate equivalenti nelle versioni API precedenti, consulta la sezione Salvataggio di file condivisi.Context.getExternalFilesDir
(Environment.DIRECTORY_PICTURES
): questo metodo restituisce una posizione standard per il salvataggio immagini e video associati alla tua applicazione. Se la tua applicazione viene disinstallata, tutti i file salvati in questa posizione verranno rimossi. La sicurezza non viene applicata per i file in questo posizione e altre applicazioni potrebbero leggerle, modificarle ed eliminarle.
Il seguente codice di esempio mostra come creare una posizione File
o Uri
per un file multimediale da utilizzare quando si chiama la fotocamera di un dispositivo con
un Intent
o nell'ambito di una creazione di una videocamera
App.
Kotlin
val MEDIA_TYPE_IMAGE = 1 val MEDIA_TYPE_VIDEO = 2 /** Create a file Uri for saving an image or video */ private fun getOutputMediaFileUri(type: Int): Uri { return Uri.fromFile(getOutputMediaFile(type)) } /** Create a File for saving an image or video */ private fun getOutputMediaFile(type: Int): File? { // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. val mediaStorageDir = File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp" ) // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist mediaStorageDir.apply { if (!exists()) { if (!mkdirs()) { Log.d("MyCameraApp", "failed to create directory") return null } } } // Create a media file name val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date()) return when (type) { MEDIA_TYPE_IMAGE -> { File("${mediaStorageDir.path}${File.separator}IMG_$timeStamp.jpg") } MEDIA_TYPE_VIDEO -> { File("${mediaStorageDir.path}${File.separator}VID_$timeStamp.mp4") } else -> null } }
Java
public static final int MEDIA_TYPE_IMAGE = 1; public static final int MEDIA_TYPE_VIDEO = 2; /** Create a file Uri for saving an image or video */ private static Uri getOutputMediaFileUri(int type){ return Uri.fromFile(getOutputMediaFile(type)); } /** Create a File for saving an image or video */ private static File getOutputMediaFile(int type){ // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "MyCameraApp"); // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist if (! mediaStorageDir.exists()){ if (! mediaStorageDir.mkdirs()){ Log.d("MyCameraApp", "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File mediaFile; if (type == MEDIA_TYPE_IMAGE){ mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg"); } else if(type == MEDIA_TYPE_VIDEO) { mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_"+ timeStamp + ".mp4"); } else { return null; } return mediaFile; }
Nota: Environment.getExternalStoragePublicDirectory()
è disponibile su Android 2.2 (livello API 8) oppure
in alto. Se scegli come target dispositivi con versioni precedenti di Android, utilizza Environment.getExternalStorageDirectory()
. Per ulteriori informazioni, vedi Salvataggio di file condivisi.
Affinché l'URI supporti i profili di lavoro, per prima cosa
l'URI del file in un URI dei contenuti. Quindi, aggiungi l'URI dei contenuti a
EXTRA_OUTPUT
di Intent
.
Per ulteriori informazioni sul salvataggio di file su un dispositivo Android, consulta Spazio di archiviazione dei dati.
Funzionalità della fotocamera
Android supporta un'ampia gamma di funzionalità della fotocamera che puoi controllare con l'applicazione.
come formato dell'immagine, modalità flash, impostazioni di messa a fuoco e molto altro ancora. Questa sezione elenca i
funzionalità della fotocamera e spiega brevemente come utilizzarle. È possibile accedere alla maggior parte delle funzionalità della fotocamera e impostarle
utilizzando l'oggetto through Camera.Parameters
. Tuttavia, ci sono diversi
funzionalità importanti che richiedono più di semplici impostazioni in Camera.Parameters
. Queste funzionalità sono trattate nelle sezioni seguenti:
Per informazioni generali su come utilizzare le funzionalità controllate tramite Camera.Parameters
, consulta le sezioni relative all'uso della fotocamera
funzionalità. Per informazioni più dettagliate su come utilizzare le funzionalità controllate tramite
camera parametri, segui i link nell'elenco delle funzionalità di seguito per andare al riferimento API
documentazione.
Tabella 1. Funzionalità comuni della fotocamera ordinate in base al livello API Android in cui vengono sono stati introdotti.
Funzionalità | Livello API | Descrizione |
---|---|---|
Rilevamento facciale | 14 | Identifica i volti umani in un'immagine e usali per la messa a fuoco, la misurazione e il bianco saldo |
Misurazione delle aree | 14 | Specifica una o più aree all'interno di un'immagine per calcolare il bilanciamento del bianco |
Aree di intervento | 14 | Imposta una o più aree di un'immagine da utilizzare per la messa a fuoco |
White Balance Lock |
14 | Interrompere o avviare le regolazioni automatiche del bilanciamento del bianco |
Exposure Lock |
14 | Interrompere o avviare le regolazioni automatiche dell'esposizione |
Video Snapshot |
14 | Scattare una foto durante la ripresa del video (fotogramma) |
Video time-lapse | 11 | Registra fotogrammi con ritardi impostati per registrare un video in time-lapse |
Multiple Cameras |
9 | Supporto di più fotocamere su un dispositivo, incluse quelle anteriore e posteriore videocamere |
Focus Distance |
9 | Segnala le distanze tra la fotocamera e gli oggetti che sembrano essere a fuoco |
Zoom |
8 | Imposta l'ingrandimento dell'immagine |
Exposure
Compensation |
8 | Aumenta o diminuisci il livello di esposizione alla luce |
GPS Data |
5 | Includi oppure ometti nell'immagine i dati sulla posizione geografica |
White Balance |
5 | Imposta la modalità di bilanciamento del bianco, che influisce sui valori dei colori nell'immagine acquisita |
Focus Mode |
5 | Imposta la modalità di messa a fuoco su un soggetto, ad esempio automatica, fissa, macro o infinito |
Scene Mode |
5 | Applicare una modalità preimpostata per tipi specifici di situazioni fotografiche, ad esempio di notte, in spiaggia e sulla neve o scene a lume di candela |
JPEG Quality |
5 | Imposta il livello di compressione per un'immagine JPEG, che aumenta o diminuisce il file di output dell'immagine qualità e dimensioni |
Flash Mode |
5 | Attivare, disattivare il flash o utilizzare l'impostazione automatica |
Color Effects |
5 | Applica un effetto cromatico all'immagine acquisita, ad esempio bianco e nero, seppia o negativo. |
Anti-Banding |
5 | Riduce l'effetto delle banding nelle sfumature di colore dovuto alla compressione JPEG |
Picture Format |
1 | Specifica il formato file per l'immagine |
Picture Size |
1 | Specifica le dimensioni in pixel dell'immagine salvata |
Nota:queste funzionalità non sono supportate su tutti i dispositivi a causa di differenze hardware e implementazione software. Per informazioni sulla verifica della disponibilità di funzionalità sul dispositivo su cui è in esecuzione l'applicazione, consulta la sezione Verificare la disponibilità delle funzionalità.
Verifica della disponibilità della funzionalità in corso...
La prima cosa da capire quando decidi di usare le funzionalità della fotocamera sui dispositivi Android è che non tutte le funzionalità della fotocamera sono supportate su tutti i dispositivi. Inoltre, i dispositivi che supportano un particolare funzionalità può supportarli con livelli diversi o con opzioni differenti. Pertanto, parte del tuo durante lo sviluppo di un'applicazione di fotocamera è decidere quali funzionalità della videocamera assistenza e a quale livello. Una volta presa questa decisione, dovresti pianificare l'inclusione del codice nei videocamera che controlla se l'hardware del dispositivo supporta queste funzionalità e non va a buon fine in modo controllato se una funzione non è disponibile.
Puoi verificare la disponibilità delle funzionalità della videocamera ricevendo un'istanza dei parametri di una videocamera
e controllando i metodi pertinenti. Il seguente esempio di codice mostra come ottenere un
Camera.Parameters
oggetto e controlla se la fotocamera supporta la messa a fuoco automatica
funzionalità:
Kotlin
val params: Camera.Parameters? = camera?.parameters val focusModes: List<String>? = params?.supportedFocusModes if (focusModes?.contains(Camera.Parameters.FOCUS_MODE_AUTO) == true) { // Autofocus mode is supported }
Java
// get Camera parameters Camera.Parameters params = camera.getParameters(); List<String> focusModes = params.getSupportedFocusModes(); if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { // Autofocus mode is supported }
Puoi utilizzare la tecnica mostrata in precedenza per la maggior parte delle funzionalità della fotocamera. La
L'oggetto Camera.Parameters
fornisce un metodo getSupported...()
, is...Supported()
o getMax...()
per determinare se (e in quale misura) una caratteristica è
supportati.
Se la tua applicazione richiede determinate caratteristiche della fotocamera per funzionare correttamente, puoi richiederle tramite aggiunte al file manifest dell'applicazione. Quando dichiari l'utilizzo di specifiche funzionalità della fotocamera, come il flash e la messa a fuoco automatica, Google Play impedisce alla tua applicazione su dispositivi che non supportano queste funzionalità. Per un elenco di funzionalità della fotocamera che puoi dichiarare nel file manifest dell'app, consulta il file manifest Funzionalità Riferimento.
Utilizzo delle funzionalità della fotocamera
La maggior parte delle funzionalità della fotocamera viene attivata e controllata utilizzando un oggetto Camera.Parameters
. Puoi ottenere questo oggetto ottenendo prima un'istanza
l'oggetto Camera
, chiamando il metodo getParameters()
, modificando il parametro restituito
per poi riposizionarlo nell'oggetto videocamera, come mostrato nell'esempio seguente
codice:
Kotlin
val params: Camera.Parameters? = camera?.parameters params?.focusMode = Camera.Parameters.FOCUS_MODE_AUTO camera?.parameters = params
Java
// get Camera parameters Camera.Parameters params = camera.getParameters(); // set the focus mode params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); // set Camera parameters camera.setParameters(params);
Questa tecnica funziona per quasi tutte le funzionalità della fotocamera e la maggior parte dei parametri può essere modificata in qualsiasi
di tempo dopo aver ottenuto un'istanza dell'oggetto Camera
. Modifiche a
sono generalmente visibili all'utente immediatamente nell'anteprima della fotocamera dell'applicazione.
Sul lato software, le modifiche ai parametri possono richiedere diversi frame per diventare effettive, poiché
l'hardware della videocamera elabora le nuove istruzioni, quindi invia i dati immagine aggiornati.
Importante:alcune funzionalità della fotocamera non possono essere modificate a piacere. Nella particolare, la modifica delle dimensioni o dell'orientamento dell'anteprima della fotocamera richiede prima l'interruzione visualizzare l'anteprima, modificare le dimensioni e riavviare l'anteprima. A partire da Android 4.0 (API livello 14) può essere modificato senza riavviare l'anteprima.
L'implementazione di altre funzionalità della fotocamera richiede più codice, tra cui:
- Misurazione e aree di messa a fuoco
- Riconoscimento facciale
- Video in time-lapse
Nelle sezioni seguenti viene fornita una rapida panoramica su come implementare queste funzionalità.
Misurazione e aree di messa a fuoco
In alcuni scenari fotografici, la messa a fuoco automatica e la misurazione della luce potrebbero non produrre per ottenere i risultati desiderati. A partire da Android 4.0 (Livello API 14), l'applicazione Fotocamera può fornire controlli aggiuntivi per consentire alla tua app o ai tuoi utenti di specificare le aree di un'immagine da utilizzare per determinare le impostazioni di messa a fuoco o del livello di luce e passa questi valori all'hardware della fotocamera per l'acquisizione immagini o video.
Le aree di misurazione e messa a fuoco funzionano in modo molto simile ad altre funzionalità della fotocamera, in quanto controllano
tramite metodi nell'oggetto Camera.Parameters
. Il seguente codice
mostra l'impostazione di due aree di misurazione della luce per un
Camera
:
Kotlin
// Create an instance of Camera camera = getCameraInstance() // set Camera parameters val params: Camera.Parameters? = camera?.parameters params?.apply { if (maxNumMeteringAreas > 0) { // check that metering areas are supported meteringAreas = ArrayList<Camera.Area>().apply { val areaRect1 = Rect(-100, -100, 100, 100) // specify an area in center of image add(Camera.Area(areaRect1, 600)) // set weight to 60% val areaRect2 = Rect(800, -1000, 1000, -800) // specify an area in upper right of image add(Camera.Area(areaRect2, 400)) // set weight to 40% } } camera?.parameters = this }
Java
// Create an instance of Camera camera = getCameraInstance(); // set Camera parameters Camera.Parameters params = camera.getParameters(); if (params.getMaxNumMeteringAreas() > 0){ // check that metering areas are supported List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>(); Rect areaRect1 = new Rect(-100, -100, 100, 100); // specify an area in center of image meteringAreas.add(new Camera.Area(areaRect1, 600)); // set weight to 60% Rect areaRect2 = new Rect(800, -1000, 1000, -800); // specify an area in upper right of image meteringAreas.add(new Camera.Area(areaRect2, 400)); // set weight to 40% params.setMeteringAreas(meteringAreas); } camera.setParameters(params);
L'oggetto Camera.Area
contiene due parametri di dati: un oggetto Rect
per specificare un'area all'interno del campo visivo della fotocamera e un peso
che indica alla videocamera il livello di importanza che attribuisci a quest'area per la misurazione della luce.
o i calcoli del focus.
Il campo Rect
in un oggetto Camera.Area
descrive una forma rettangolare mappata su una griglia di 2000 x 2000 unità. Le coordinate -1000, -1000
rappresenta l'angolo superiore sinistro dell'immagine della fotocamera, mentre le coordinate 1000, 1000 rappresentano
nell'angolo inferiore destro dell'immagine della fotocamera, come mostrato nell'illustrazione seguente.
Figura 1. Le linee rosse indicano il sistema di coordinate per specificare una
Camera.Area
in un'anteprima della fotocamera. La casella blu mostra la posizione
forma di un'area di una fotocamera con i valori Rect
333.333.667.667.
I limiti di questo sistema di coordinate corrispondono sempre al bordo esterno dell'immagine visibile
l'anteprima della fotocamera e non ridurre o espandere il livello di zoom. Analogamente, la rotazione dell'immagine
anteprima con Camera.setDisplayOrientation()
non rimappa il sistema di coordinate.
Riconoscimento facciale
Per le foto che includono persone, i volti di solito sono la parte più importante dell'immagine. Inoltre, deve essere utilizzato per determinare sia la messa a fuoco sia il bilanciamento del bianco durante l'acquisizione di un'immagine. Android 4.0 (livello API 14) fornisce API per identificare i volti e calcolare le impostazioni delle immagini utilizzando di riconoscimento facciale.
Nota:mentre è attiva la funzione di rilevamento dei volti,
setWhiteBalance(String)
,
setFocusAreas(List<Camera.Area>)
e
setMeteringAreas(List<Camera.Area>)
non hanno alcun effetto.
Per utilizzare la funzionalità di rilevamento dei volti nell'applicazione della fotocamera sono necessari alcuni passaggi generali:
- Verifica che il rilevamento dei volti sia supportato sul dispositivo
- Crea un listener di rilevamento dei volti
- Aggiungere il listener di rilevamento dei volti all'oggetto della videocamera
- Avvia il rilevamento dei volti dopo l'anteprima (e dopo ogni riavvio dell'anteprima)
La funzionalità di rilevamento dei volti non è supportata su tutti i dispositivi. Puoi verificare che questa funzionalità
supportato chiamando getMaxNumDetectedFaces()
. Un
un esempio di questo controllo è mostrato nel metodo campione startFaceDetection()
riportato di seguito.
Per ricevere una notifica e rispondere al rilevamento di un volto, l'applicazione della videocamera deve impostare
un listener per gli eventi di rilevamento dei volti. A tale scopo, devi creare una classe listener che
implementa l'interfaccia Camera.FaceDetectionListener
come mostrato
di esempio qui sotto.
Kotlin
internal class MyFaceDetectionListener : Camera.FaceDetectionListener { override fun onFaceDetection(faces: Array<Camera.Face>, camera: Camera) { if (faces.isNotEmpty()) { Log.d("FaceDetection", ("face detected: ${faces.size}" + " Face 1 Location X: ${faces[0].rect.centerX()}" + "Y: ${faces[0].rect.centerY()}")) } } }
Java
class MyFaceDetectionListener implements Camera.FaceDetectionListener { @Override public void onFaceDetection(Face[] faces, Camera camera) { if (faces.length > 0){ Log.d("FaceDetection", "face detected: "+ faces.length + " Face 1 Location X: " + faces[0].rect.centerX() + "Y: " + faces[0].rect.centerY() ); } } }
Dopo aver creato questa classe, puoi impostarla nel
Camera
, come mostrato nel codice di esempio riportato di seguito:
Kotlin
camera?.setFaceDetectionListener(MyFaceDetectionListener())
Java
camera.setFaceDetectionListener(new MyFaceDetectionListener());
L'applicazione deve avviare la funzione di rilevamento dei volti ogni volta che avvii (o riavvii) la l'anteprima della fotocamera. Crea un metodo per avviare il rilevamento dei volti in modo da poter chiamare in base alle esigenze, come mostrato nel codice di esempio riportato di seguito.
Kotlin
fun startFaceDetection() { // Try starting Face Detection val params = mCamera?.parameters // start face detection only *after* preview has started params?.apply { if (maxNumDetectedFaces > 0) { // camera supports face detection, so can start it: mCamera?.startFaceDetection() } } }
Java
public void startFaceDetection(){ // Try starting Face Detection Camera.Parameters params = mCamera.getParameters(); // start face detection only *after* preview has started if (params.getMaxNumDetectedFaces() > 0){ // camera supports face detection, so can start it: mCamera.startFaceDetection(); } }
Il rilevamento dei volti deve essere attivato ogni volta che avvii (o riavvii) l'anteprima della videocamera. Se
che utilizzi il corso di anteprima mostrato in Creazione di un corso in anteprima, aggiungi
startFaceDetection()
in entrambi i casi
surfaceCreated()
e surfaceChanged()
nel corso in anteprima,
come mostrato nel codice campione di seguito.
Kotlin
override fun surfaceCreated(holder: SurfaceHolder) { try { mCamera.setPreviewDisplay(holder) mCamera.startPreview() startFaceDetection() // start face detection feature } catch (e: IOException) { Log.d(TAG, "Error setting camera preview: ${e.message}") } } override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) { if (holder.surface == null) { // preview surface does not exist Log.d(TAG, "holder.getSurface() == null") return } try { mCamera.stopPreview() } catch (e: Exception) { // ignore: tried to stop a non-existent preview Log.d(TAG, "Error stopping camera preview: ${e.message}") } try { mCamera.setPreviewDisplay(holder) mCamera.startPreview() startFaceDetection() // re-start face detection feature } catch (e: Exception) { // ignore: tried to stop a non-existent preview Log.d(TAG, "Error starting camera preview: ${e.message}") } }
Java
public void surfaceCreated(SurfaceHolder holder) { try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); startFaceDetection(); // start face detection feature } catch (IOException e) { Log.d(TAG, "Error setting camera preview: " + e.getMessage()); } } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { if (holder.getSurface() == null){ // preview surface does not exist Log.d(TAG, "holder.getSurface() == null"); return; } try { mCamera.stopPreview(); } catch (Exception e){ // ignore: tried to stop a non-existent preview Log.d(TAG, "Error stopping camera preview: " + e.getMessage()); } try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); startFaceDetection(); // re-start face detection feature } catch (Exception e){ // ignore: tried to stop a non-existent preview Log.d(TAG, "Error starting camera preview: " + e.getMessage()); } }
Nota: ricorda di chiamare questo metodo dopo la chiamata
startPreview()
. Non tentare di avviare il rilevamento dei volti
nel metodo onCreate()
dell'attività principale dell'app Fotocamera,
poiché a questo punto l'anteprima non è più disponibile
nell'esecuzione dell'applicazione.
Video in time-lapse
I video in time-lapse consentono agli utenti di creare video clip che combinano immagini scattate qualche secondo oppure
minuti l'uno dall'altro. Questa funzionalità utilizza MediaRecorder
per registrare le immagini per un periodo di tempo
sequenza di interruzioni.
Per registrare un video in time-lapse con MediaRecorder
, devi configurare la
registratore come se stessi registrando un video normale, impostando i fotogrammi al secondo acquisiti su un
numero basso e utilizzare una delle impostazioni di qualità del time-lapse, come mostrato nell'esempio di codice riportato di seguito.
Kotlin
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH)) mediaRecorder.setCaptureRate(0.1) // capture a frame every 10 seconds
Java
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher) mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH)); ... // Step 5.5: Set the video capture rate to a low number mediaRecorder.setCaptureRate(0.1); // capture a frame every 10 seconds
Queste impostazioni devono essere eseguite nell'ambito di una procedura di configurazione più ampia per MediaRecorder
. Per un esempio di codice di configurazione completo, consulta Configurazione di MediaRecorder. Una volta completata la configurazione,
avvii la registrazione video come se stessi registrando un normale video clip. Per ulteriori informazioni
Informazioni sulla configurazione e sull'esecuzione di MediaRecorder
, consulta l'articolo Acquisizione di video.
L'immagine Camera2Video e HdrViewfinder esempi dimostrano ulteriormente l'uso delle API trattate in questa pagina.
Campi relativi alla fotocamera che richiedono l'autorizzazione
Per le app con Android 10 (livello API 29) o versioni successive è necessario
Autorizzazione CAMERA
per
accedere ai valori dei seguenti campi che
getCameraCharacteristics()
restituisce:
LENS_POSE_ROTATION
LENS_POSE_TRANSLATION
LENS_INTRINSIC_CALIBRATION
LENS_RADIAL_DISTORTION
LENS_POSE_REFERENCE
LENS_DISTORTION
LENS_INFO_HYPERFOCAL_DISTANCE
LENS_INFO_MINIMUM_FOCUS_DISTANCE
SENSOR_REFERENCE_ILLUMINANT1
SENSOR_REFERENCE_ILLUMINANT2
SENSOR_CALIBRATION_TRANSFORM1
SENSOR_CALIBRATION_TRANSFORM2
SENSOR_COLOR_TRANSFORM1
SENSOR_COLOR_TRANSFORM2
SENSOR_FORWARD_MATRIX1
SENSOR_FORWARD_MATRIX2
Codice campione aggiuntivo
Per scaricare app di esempio, consulta la Esempio di Camera2Basic e App ufficiale di esempio CameraX.