Android Essentials crea uno specchio

Scopri come creare una semplice app "mirror" in questo rapido tutorial!

Uno degli usi inaspettati dei telefoni cellulari, con i loro schermi lucenti, è che la gente ha cominciato a usarli come specchi per controllare i capelli, il rossetto o solo per assicurarsi che nessun broccolo si sia incastrato tra i denti. Quando sono arrivati ​​i cellulari con fotocamera, le persone si sono subito imposte l'obiettivo su autoritratti, anche se ciò significava contorcersi in strani modi per ottenere il colpo. I produttori di hardware hanno sfruttato questo concetto creando una nuova generazione di smartphone con due fotocamere: una rivolta verso l'esterno e una rivolta verso la fotocamera frontale. Questo hardware si presta a tutti i tipi di applicazioni pratiche.

A partire dal livello API 9, l'SDK di Android ha fornito un metodo per accedere a più telecamere sui dispositivi. E da allora, la maggior parte dei produttori ha incluso una fotocamera frontale. Questa fotocamera viene solitamente utilizzata per scattare autoritratti o per scopi di chat video.


Passaggio 0: Introduzione

Il codice sorgente aperto per questo progetto può essere scaricato e utilizzato localmente o sfogliato online. In alternativa, puoi creare il tuo progetto. Questo è un progetto a singola attività, quindi puoi aggiungere l'attività anche al tuo progetto. Supponiamo che tu abbia un progetto pronto per lavorare.


Passaggio 1: Layout della videocamera

Un tipico modo di presentare la fotocamera è la creazione di un layout, a piacere, con un controllo FrameLayout per tenere l'anteprima della fotocamera. Di solito c'è una sorta di pulsante per scattare una foto. Con questo in mente, ecco il layout che abbiamo usato per la modalità verticale:

    

La disposizione del paesaggio è simile, ma il pulsante si trova lungo il lato.


Passaggio 2: avvio della fotocamera

Si accede alle telecamere del dispositivo usando la classe Camera (android.hardware.Camera) dell'SDK Android. Un punto ragionevole per configurare e avviare la videocamera è nel metodo onCreate () della tua classe Activity, in questo modo:

macchina fotografica privata mCam; MirrorView privato mCamPreview; private int mCameraId = 0; frameLayout privato mPreviewLayout; @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main); mCameraId = findFirstFrontFacingCamera (); mPreviewLayout = (FrameLayout) findViewById (R.id.camPreview); mPreviewLayout.removeAllViews (); startCameraInLayout (mPreviewLayout, mCameraId); 

Per prima cosa, determiniamo quale telecamera è la fotocamera anteriore. Poiché l'API prevede la possibilità di più di una fotocamera frontale, usiamo la prima. Successivamente, FrameLayout viene caricato e cancellato. Vogliamo solo l'anteprima della fotocamera al suo interno. Quindi, finalmente, iniziamo la fotocamera in questo layout.

Ora diamo un'occhiata a ciascuno di questi metodi di supporto.


Passaggio 3: ricerca di una fotocamera anteriore

Utilizzare il metodo getNumberOfCameras () dell'oggetto Camera per scorrere su ciascuna istanza della telecamera e recuperare un oggetto CameraInfo. Usa il campo fronte per determinare se la camera è un CAMERA_FACING_FRONT. In tal caso, restituisci l'id della telecamera: abbiamo trovato una fotocamera frontale da utilizzare.

int privato findFirstFrontFacingCamera () int foundId = -1; int numCams = Camera.getNumberOfCameras (); for (int camId = 0; camId < numCams; camId++)  CameraInfo info = new CameraInfo(); Camera.getCameraInfo(camId, info); if (info.facing == CameraInfo.CAMERA_FACING_FRONT)  foundId = camId; break;   return foundId; 

Passaggio 4: avvio della fotocamera anteriore

Quindi, recuperare un'istanza dell'oggetto Camera con una chiamata al metodo Camera.open () utilizzando l'identificatore della telecamera per la fotocamera frontale. Creare un'istanza di un oggetto MirrorView utilizzando la videocamera aperta e aggiungere l'oggetto MirrorView al layout.

private void startCameraInLayout (layout FrameLayout, int cameraId) mCam = Camera.open (cameraId); if (mCam! = null) mCamPreview = new MirrorView (this, mCam); layout.addView (mCamPreview); 

Ora diamo un'occhiata più da vicino alla classe MirrorView.


Passaggio 5: creazione di MirrorView

Per posizionare l'anteprima sullo schermo per visualizzare ciò che la fotocamera sta acquisendo, dobbiamo creare un nuovo SurfaceView in modo che possiamo assegnare il suo supporto (SurfaceHolder) all'hardware della videocamera. Ciò consente all'hardware della fotocamera di scrivere direttamente sulla superficie.

Ecco l'implementazione del nostro MirrorView:

public class MirrorView estende SurfaceView implementa SurfaceHolder.Callback private SurfaceHolder mHolder; macchina fotografica privata mCamera; MirrorView pubblico (Contesto contesto, Telecamera) super (contesto); mCamera = camera; mHolder = getHolder (); mHolder.addCallback (questo); mHolder.setType (SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  public void surfaceCreated (titolare di SurfaceHolder) try mCamera.setPreviewDisplay (titolare); mCamera.startPreview ();  catch (Eccezione errore) Log.d (DEBUG_TAG, "Errore durante l'avvio di mPreviewLayout:" + error.getMessage ());  public void surfaceDestroyed (proprietario di SurfaceHolder)  public void surfaceChanged (titolare di SurfaceHolder, int format, int w, int h) if (mHolder.getSurface () == null) return;  // non può apportare modifiche mentre mPreviewLayout è attivo try mCamera.stopPreview ();  catch (Exception e)  try // avvia mPreviewLayout mCamera.setPreviewDisplay (mHolder); mCamera.startPreview ();  catch (Eccezione errore) Log.d (DEBUG_TAG, "Errore durante l'avvio di mPreviewLayout:" + error.getMessage ()); 

Quando viene creata la superficie, nella chiamata su SurfaceCreated (), la fotocamera SurfaceHolder viene impostata e l'anteprima viene avviata con una chiamata al metodo startPreview (). Quando la superficie viene cambiata, nella chiamata su SurfaceChanged (), la telecamera viene arrestata e riavviata con il supporto aggiornato. Per la completa implementazione di questa soluzione, con le dichiarazioni per DEBUG_TAG e simili, consultare il codice sorgente completo.

Se questo è tutto ciò che fai, l'applicazione funzionerà. Tuttavia, i risultati non saranno ideali. Probabilmente, l'anteprima apparirà lateralmente e il formato non sarà corretto, facendo apparire il tuo viso allungato o schiacciato. Non bene!


Passaggio 6: regolazione per l'orientamento della videocamera e il rapporto di aspetto

L'orientamento dell'anteprima della videocamera deve corrispondere all'orientamento dello schermo del dispositivo affinché tutto appaia correttamente. Inoltre, il rapporto di aspetto dell'anteprima della fotocamera deve corrispondere alla dimensione dell'anteprima, altrimenti l'immagine apparirà deformata. Tutti questi dati sono facilmente disponibili dalle classi Display, CameraInfo e Camera.Parameters. Qui abbiamo scritto un semplice metodo che regola le caratteristiche di visualizzazione di SurfaceHolder per risolvere questi problemi:

public void setCameraDisplayOrientationAndSize () CameraInfo info = new CameraInfo (); Camera.getCameraInfo (mCameraId, informazioni); int rotation = getWindowManager (). getDefaultDisplay (). getRotation (); int gradi = rotazione * 90; risultato int; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) result = (info.orientation + degrees)% 360; risultato = (360 - risultato)% 360;  else result = (info.orientation - degrees + 360)% 360;  mCamera.setDisplayOrientation (risultato); Camera.Size previewSize = mCam.getParameters (). GetPreviewSize (); if (risultato == 90 || risultato == 270) mHolder.setFixedSize (previewSize.height, previewSize.width);  else mHolder.setFixedSize (previewSize.width, previewSize.height); 

A questo punto, lo specchio dovrebbe essere perfettamente funzionante.


Passaggio 7: pulizia

L'oggetto Camera deve essere rilasciato non appena la tua app avrà terminato. Nel caso dell'attività di esempio, possiamo rilasciare la fotocamera nel metodo onPause () e avviarla in onResume (), in questo modo:

@Override protected void onResume () super.onResume (); if (mCam == null && mPreviewLayout! = null) mPreviewLayout.removeAllViews (); startCameraInLayout (mPreviewLayout, mCameraId);  @Override protected void onPause () if (mCam! = Null) mCam.release (); mCam = null;  super.onPause (); 

Conclusione

Non sottovalutare mai quanto gli utenti amano le loro fotocamere anteriori. Molti degli smartphone di ultima generazione hanno questa caratteristica, ma poche applicazioni ne approfittano: il tuo dovrebbe! Hai imparato come identificare e utilizzare le fotocamere anteriori in questo tutorial. Inoltre, hai imparato come regolare l'orientamento dello schermo e le proporzioni della sezione di anteprima.

Puoi salvare l'immagine ora? (Suggerimento: hai scaricato il codice open source, giusto?)


Riguardo agli Autori

Gli sviluppatori mobili Lauren Darcey e Shane Conder hanno coautore diversi libri sullo sviluppo di Android: un libro di programmazione approfondito intitolato Sviluppo di applicazioni wireless Android e Sams ti insegna a sviluppare applicazioni Android in 24 ore. Quando non scrivono, passano il loro tempo a sviluppare software mobile presso la loro azienda ea fornire servizi di consulenza. Possono essere contattati via email a [email protected], tramite il loro blog su androidbook.blogspot.com e su Twitter @androidwireless.