2014-11-16 2 views
11

Я пытаюсь захватить фотографии непосредственно с помощью API камеры, но это предварительный просмотр я получил: enter image description hereAndroid: Взятые фото больше чем превью

& это изображение, полученное после вызова takePicture() которых больше, чем сама предпросмотре:

enter image description here

(примечание: Я обрезается высоту предыдущих 2 фотографии для повышения читаемости вопроса, & сохранил ширину, как это)

Я использую этот метод полезности выбрать наилучший оптимальный размер предварительного просмотра перед началом предварительного просмотра камеры:

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); 
} 

& этот метод, чтобы выбрать подходящий размер изображения:

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); 
} 

& это является элемент предварительного просмотра камеры на схеме:

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

& Я следую за the official documentation для создания самого предварительного просмотра камеры

Итак, как заставить предварительный просмотр камеры показать точную фотографию, которая будет снята?

ответ

16

Наконец я нашел :)

в соответствии с этим answer & цитирую:

В то время как типичная камера является 4: 3 аспект, предварительный просмотр также может быть доступен в 5 : 3 и 16: 9, и это, по-видимому, достигается путем фактического расширения горизонтального поля обзора ...

Поэтому нам нужно найти предварительный просмотр si зе & размер картины, как с 4: 3 соотношение сторон, чтобы иметь возможность использовать полный угол камеры, поэтому я изменил мой код, как это:

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

кажется довольно бесценной информацией здесь! – Fattie

2

Вы должны запустить тот же цикл над размерами, возвращаемыми parameters.getSupportedPictureSizes(), и не полагаться на размер изображения по умолчанию. Кроме того, я предпочел бы наилучшую соответствующую пару параметров предварительного просмотра/изображения, и пусть изображение будет обрезано на экране, если это соотношение сторон не соответствует формату кадра cameraPreview.

+0

Ну, я редактировал вопрос добавить метод, который я использую для выбора размера изображения. Но я думаю, что это все о предварительном просмотре, потому что он не показывает полный возможный угол камеры, как сделанный снимок. Я попытался сравнить поверхность предварительного просмотра с тем, что было в Instagram, и предварительный просмотр Instagram показал полный угол, как изображение, сделанное моим кодом, так что проблема в моем предварительном просмотре как-то – AbdelHady

+0

Какие размеры вы получаете на своем устройстве? Имеют ли они одинаковое соотношение сторон? –

+0

Ну, методы, которые я использую, дали мне следующее на LG-G2: размер предварительного просмотра - 1776X1080, а размер изображения - 3264X2448. – AbdelHady

Смежные вопросы