2013-05-24 3 views
28

Ho sviluppato una piccola applicazione per visualizzare l'anteprima della fotocamera a schermo intero. Sto usando l'API della fotocamera per questo.La visualizzazione/anteprima della fotocamera a schermo intero non mantiene le proporzioni - l'immagine è inclinata, allungata per adattarsi allo schermo

Questo è il layout attività:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:orientation="vertical" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent"> 

    <!-- This is the container for the camera preview screen --> 
    <FrameLayout android:id="@+id/camera_preview" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content"/> 
</LinearLayout> 

Quando il dispositivo è in verticale, il display verticalmente scalato per adattare l'altezza dello schermo del dispositivo - quindi il rapporto di aspetto non è la stessa di quella da macchina fotografica nativa. Questi sono 2 immagini che spiega meglio quello che sto dicendo:

enter image description hereenter image description here

La prima immagine è fatto con fotocamera del dispositivo nativo. La seconda immagine è realizzata con la mia app, con la fotocamera a schermo intero - l'immagine è inclinata, allungata per adattarsi allo schermo.

Ho bisogno che l'anteprima della fotocamera sia a schermo intero, indipendentemente dalle dimensioni dell'anteprima fornite dal metodo getSupportedPreviewSizes() e senza distorsioni. C'è un modo per realizzare questo? C'è un modo per mantenere le proporzioni corrette quando l'anteprima della fotocamera è a schermo intero? Mi aspettavo che ciò venisse eseguito automaticamente dal sistema operativo, ritagliando l'immagine in modo che corrisponda alla risoluzione richiesta mantenendo le proporzioni, ma ciò non accade.

Ho cercato di rendere il SurfaceView più grande del display (seguendo questa domanda: Fitting a camera preview to a SurfaceView larger than the display), ma non è ok nel mio caso poiché sono istantanee di cattura (6 fotogrammi/secondo) e quelle non sono quelle che l'utente vede sullo schermo (la cornice contiene tutte le anteprime della fotocamera anche se non tutte sono visibili sullo schermo).

Ho postato qui: https://www.dropbox.com/s/3d52xt8kazynsae/CameraFullScreen.7z?v=0mcn l'intero progetto che ho realizzato.

Qualsiasi idea/soluzione è più importante per me. Molte grazie.

========================================= ==========================

aggiornamento a causa di ss1271 risposta:

analizzerò un po 'le risoluzioni hai scritto sopra per Samsung Galaxy Ace II.

I. Risoluzione dello schermo: 480x800 - aspect ratio 3: 5 = 0,6

II. getSupportedPreviewSizes - Sono quasi sicuro che questi valori provengano dalla fotocamera posteriore. Qui di seguito sono il rapporto di aspetto per queste risoluzioni:

2560x1920 - 0,75 

    2560x1536 - 0,60 

    2048x1536 - 0,75 

    2048x1232 - 0,60 

    960x720  - 0,75 

    640x480  - 0,75 

Così, il metodo restituisce un Size corrispondente a 2560x1536 o per 2048x1232 - questi hanno le stesse proporzioni di risoluzione dello schermo e l'utilizzo di questi valori non distorcere l'immagine. Il problema per me è che non posso usare risoluzioni così grandi da quando catturo 6 fotogrammi al secondo e questi devono essere salvati a una risoluzione più bassa.

mi presento qui di seguito alcuni risultati da un dispositivoSamsung S2:

I. Risoluzione dello schermo: 480 x 800 - aspect ratio 3: 5 = 0,6

II. Telecamera posteriore
a). getSupportedPreviewSizes:

800/480 - 480/800 = 0,60 
800/450 - 450/800 = 0,56 
720/480 - 0,66 
640/480 - 0,75 
352/288 - 0,81 
320/240 - 0,75 
176/144 - 0,81 

b). Risoluzioni delle telecamere native:

3264/2448 - 0,75 - not full screen 
3264/1968 - 0,60 - FULL SCREEN (since has the same aspect ratio as device screen) 
2048/1536 - 0,75 - not full screen 
2048/1232 - 0,60 - FULL SCREEN (same aspect ratio as device screen) 
800/480 - 0,60 - FULL SCREEN (same aspect ratio as device screen) 
640/480 - 0, 75 - not full screen 

III. Fotocamera anteriore
a). getSupportedPreviewSizes:

640/480 - 0,75 
352/288 - 0,81 
320/240 - 0,75 
176/144 - 0,81 

b). La telecamera nativa non è a schermo intero e non posso scegliere una risoluzione: l'opzione è disabilitata.

Per S2, fotocamera posteriore, mi chiedo perché il metodo getSupportedPreviewSizes() non restituisca le stesse risoluzioni della fotocamera nativa o quelle visualizzate dalla fotocamera nativa sono le dimensioni delle immagini? Mi chiedo perché non ho opzioni come 3264/1968, 2048/1232 date dal metodo getSupportedPreviewSizes()? : enter image description here

+0

quello che voglio è in realtà l'anteprima della fotocamera da ritagliare al fine di mantenere le proporzioni corrette – Paul

+0

mi chiedo: hai bisogno di una fotocamera personalizzata o vuoi solo mostrare il mirino della fotocamera (anteprima)? – dumbfingers

+0

Ho una fotocamera personalizzata, con pulsanti sovrapposti. – Paul

risposta

23

In poche parole, si può fare un anteprima della fotocamera a schermo intero ma è necessario scoprire le dimensioni appropriate tra i formati supportati anteprima da soli, solo se l'anteprima della fotocamera su misura è ciò che si vuole .

Per la vostra domanda, secondo il Android Developers -- Camera

Se si desidera impostare una dimensione specifica per l'anteprima della fotocamera, impostare questo nel metodo surfaceChanged() come indicato nei commenti sopra. Quando si imposta dimensioni di anteprima, è deve utilizzare valori da getSupportedPreviewSizes(). Non impostare valori arbitrari nell' setPreviewSize()metodo.

Sembra che non sia possibile passare manualmente le dimensioni che si desidera oltre alle dimensioni fornite da getSupportedPreviewSizes(). Con un esame più approfondito delle dimensioni supportate dalla fotocamera del tuo telefono, troverai che il rapporto tra le dimensioni supportate potrebbe non essere esattamente uguale al rapporto dello schermo.

Per esempio, Samsung Galaxy Ace II ha 480x800 risoluzione dello schermo, leggendo la Size tornato da getSupportedPreviewSizes(), la sua fotocamera supporta:

2560x1920

2560x1536

2048x1536

2048x1232

960x720

640x480

e se si desidera visualizzare l'anteprima della fotocamera a schermo intero correttamente (senza stirata), è necessario calcolare, confrontare e applicare il rapporto adatto in queste dimensioni di anteprima supportati.

L'implementazione della ricerca di una dimensione di anteprima corretta non è roba complicata. Un metodo comune per fare questo sarebbe qualcosa di simile a questo:

/** 
    * Calculate the optimal size of camera preview 
    * @param sizes 
    * @param w 
    * @param h 
    * @return 
    */ 
    private Size getOptimalSize(List<Size> sizes, int w, int h) { 

     final double ASPECT_TOLERANCE = 0.2;   
     double targetRatio = (double) w/h;   
     if (sizes == null)    
      return null;   
     Size optimalSize = null;   
     double minDiff = Double.MAX_VALUE;   
     int targetHeight = h;   
     // Try to find an size match aspect ratio and size   
     for (Size size : sizes) 
     {    
//   Log.d("CameraActivity", "Checking size " + size.width + "w " + size.height + "h");    
      double ratio = (double) size.width/size.height;    
      if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)     
       continue;    
      if (Math.abs(size.height - targetHeight) < minDiff) 
      {     
       optimalSize = size;     
       minDiff = Math.abs(size.height - targetHeight);    
      }   
     }   
     // Cannot find the one match the aspect ratio, ignore the requirement  

     if (optimalSize == null) 
     { 
      minDiff = Double.MAX_VALUE;    
      for (Size size : sizes) { 
       if (Math.abs(size.height - targetHeight) < minDiff) 
       { 
        optimalSize = size; 
        minDiff = Math.abs(size.height - targetHeight); 
       } 
      } 
     } 

     SharedPreferences previewSizePref; 
     if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) { 
      previewSizePref = getSharedPreferences("PREVIEW_PREF",MODE_PRIVATE); 
     } else { 
      previewSizePref = getSharedPreferences("FRONT_PREVIEW_PREF",MODE_PRIVATE); 
     } 

     SharedPreferences.Editor prefEditor = previewSizePref.edit(); 
     prefEditor.putInt("width", optimalSize.width); 
     prefEditor.putInt("height", optimalSize.height); 

     prefEditor.commit(); 

//  Log.d("CameraActivity", "Using size: " + optimalSize.width + "w " + optimalSize.height + "h");    
     return optimalSize;  
    } 

E si può anche fare il simile per scoprire le dimensioni della fotocamera adatti (l'uscita dimensioni dell'immagine).

Nota: ho trovato la versione originale del codice sopra da Internet e ho apportato alcune modifiche/ottimizzazioni per il mio scopo.

Per favore fatemi sapere se questo funziona per voi.

+0

Innanzitutto, grazie mille per la risposta. Ho aggiornato la domanda per rispondere alla tua risposta per una migliore visibilità. La mia applicazione utilizza più fotocamera frontale rispetto alla fotocamera posteriore.Sembra che, se la fotocamera nativa non visualizza la fotocamera frontale a schermo intero (almeno non su un telefono S2 e S3) a causa del problema di proporzioni, non potrò fare lo stesso senza distorcere l'immagine ... – Paul

+0

Grazie mille! Non utilizzare setPreviewSize() ha risolto il problema per me. – BVB

+2

chiunque trovi questo thread, ti consiglio anche di guardare qui: http://stackoverflow.com/questions/17348614/make-a-surfaceview-larger-than-the-screen-fitting-a-camera-preview-to-a -superficie – Sam

0

Stavo affrontando lo stesso problema in Camera2 API, ho usato Preview size and devices aspect ratio per risolvere il problema. Puoi anche fare lo stesso con la tua API della fotocamera.