2014-11-16 19 views
11

Sto cercando di catturare le foto direttamente utilizzando l'API della fotocamera, ma questa è l'anteprima che ho ottenuto: enter image description hereAndroid: foto scattata è più grande l'anteprima

& questa è l'immagine presa dopo aver chiamato takePicture() che è più grande di quanto l'anteprima in sé:

enter image description here

(nota: ho ritagliato l'altezza delle precedenti 2 foto per migliorare la leggibilità domanda, & mantenuto la larghezza è)

Sto usando questo metodo di utilità per scegliere meglio dimensione ottimale anteprima prima di avviare la macchina fotografica anteprima:

public static Camera.Size getBestAspectPreviewSize(int displayOrientation, 
                int width, 
                int height, 
                Camera.Parameters parameters) { 
    double targetRatio = (double) width/height; 
    Camera.Size optimalSize = null; 
    double minDiff = Double.MAX_VALUE; 
    if (displayOrientation == 90 || displayOrientation == 270) { 
     targetRatio = (double) height/width; 
    } 
    List<Camera.Size> sizes = parameters.getSupportedPreviewSizes(); 
    Collections.sort(sizes, 
      Collections.reverseOrder(new SizeComparator())); 
    for (Camera.Size size : sizes) { 
     double ratio = (double) size.width/size.height; 
     if (Math.abs(ratio - targetRatio) < minDiff) { 
      optimalSize = size; 
      minDiff = Math.abs(ratio - targetRatio); 
     } 
     if (minDiff < 0.0d) { 
      break; 
     } 
    } 
    return (optimalSize); 
} 

& questo metodo per scegliere un adeguato dimensioni dell'immagine:

public static Camera.Size getBiggestSafePictureSize(Camera.Parameters parameters) { 
    Camera.Size result = null; 
    long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); 
    long availableMemory = Runtime.getRuntime().maxMemory() - used; 
    for (Camera.Size size : parameters.getSupportedPictureSizes()) { 
     int newArea = size.width * size.height; 
     long neededMemory = newArea * 4 * 4; // newArea * 4 Bytes/pixel * 4 needed copies of the bitmap (for safety :)) 
     if (neededMemory > availableMemory) 
      continue; 
     if (result == null) { 
      result = size; 
     } else { 
      int resultArea = result.width * result.height; 
      if (newArea > resultArea) { 
       result = size; 
      } 
     } 
    } 
    return (result); 
} 

& questo è il elemento anteprima fotocamera nel layout:

<FrameLayout 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:id="@+id/cameraPreview"></FrameLayout> 

& Sto seguendo the official documentation per creare l'anteprima della fotocamera stessa

Quindi, come forzare l'anteprima della fotocamera per mostrare la foto esatta che verrà scattata?

risposta

16

Infine l'ho trovato :)

secondo questa answer & cito:

Mentre la fotocamera è un tipico rapporto 4: 3 aspetto, l'anteprima potrebbe anche essere disponibile in 5 : 3 e 16: 9 e questo sembra essere ottenuto estendendo effettivamente il campo visivo orizzontale ...

Quindi dobbiamo trovare un'anteprima ze & una dimensione di immagine, sia con formato 4: 3 aspetto di essere in grado di utilizzare la piena angolo di della telecamera, quindi ho cambiato il mio codice come questo:

public static Camera.Size determineBestPreviewSize(Camera.Parameters parameters) { 
    List<Camera.Size> sizes = parameters.getSupportedPreviewSizes(); 
    return determineBestSize(sizes); 
} 

public static Camera.Size determineBestPictureSize(Camera.Parameters parameters) { 
    List<Camera.Size> sizes = parameters.getSupportedPictureSizes(); 
    return determineBestSize(sizes); 
} 

protected static Camera.Size determineBestSize(List<Camera.Size> sizes) { 
    Camera.Size bestSize = null; 
    long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); 
    long availableMemory = Runtime.getRuntime().maxMemory() - used; 
    for (Camera.Size currentSize : sizes) { 
     int newArea = currentSize.width * currentSize.height; 
     long neededMemory = newArea * 4 * 4; // newArea * 4 Bytes/pixel * 4 needed copies of the bitmap (for safety :)) 
     boolean isDesiredRatio = (currentSize.width/4) == (currentSize.height/3); 
     boolean isBetterSize = (bestSize == null || currentSize.width > bestSize.width); 
     boolean isSafe = neededMemory < availableMemory; 
     if (isDesiredRatio && isBetterSize && isSafe) { 
      bestSize = currentSize; 
     } 
    } 
    if (bestSize == null) { 
     return sizes.get(0); 
    } 
    return bestSize; 
} 
+1

sembra un'informazione inestimabile qui! – Fattie

2

È necessario eseguire lo stesso ciclo sulle dimensioni restituite da parameters.getSupportedPictureSizes() e non fare affidamento sulla dimensione dell'immagine predefinita. Inoltre, preferisco cercare la migliore coppia corrispondente di dimensioni di anteprima/immagine e lasciare che l'immagine venga ritagliata sullo schermo se questo rapporto non corrisponde alle proporzioni del layout cameraPreview.

+0

Beh, ho curato la domanda per aggiungere il metodo che uso per scegliere la dimensione dell'immagine. Ma penso che riguardi l'anteprima, perché non mostra l'angolo completo della fotocamera come la foto scattata. Ho provato a confrontare la mia superficie di anteprima con quella di Instagram, e l'anteprima di Instagram mostrava l'angolo completo come quella del mio codice, quindi il problema è nella mia anteprima in qualche modo – AbdelHady

+0

Che dimensioni ottieni sul tuo dispositivo? Sono dello stesso aspetto? –

+0

Bene, i metodi che sto usando mi hanno dato la seguente su LG-G2: la dimensione dell'anteprima è 1776X1080, e la dimensione dell'immagine è 3264X2448 – AbdelHady

Problemi correlati