Intereting Posts
Как явное указание, что приложение не поддерживает устройства LDPI Учетная запись Google Play Publisher завершена, может ли другой разработчик опубликовать мои приложения? Cannont разрешить символ JSONObject (Android Studio) Почему произошла эта ошибка? Java.lang.RuntimeException: ImageLoader должен быть init с настройкой перед использованием Получайте события касания в диалоге, который отображается сам, когда палец уже касался экрана Панель прогресса Android WebView Внедрение плавающего действия с использованием кнопки действия Float из библиотеки поддержки Android Design Android-карты v2 сбой при повторном открытии фрагмента OnTouchEvent выполняет дважды Как сгенерировать отчеты с помощью градиента? Переход интерфейса к фрагменту Как определить, было ли отклонено уведомление? Утечка памяти, вызванная методом инициализации YouTubePlayer.Provider SQLiteDatabase: Вставить только в том случае, если значение не существует (не через команду raw SQL) Утечка памяти Android WebView при использовании активов

Android: сделанное фото больше, чем предварительный просмотр

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

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

Введите описание изображения здесь

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

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

 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> 

& Я следую официальной документации для создания самого предварительного просмотра камеры

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

Solutions Collecting From Web of "Android: сделанное фото больше, чем предварительный просмотр"

Наконец я нашел это 🙂

В соответствии с этим ответом я цитирую:

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

Поэтому нам нужно найти размер предварительного просмотра и размер изображения, как с соотношением сторон 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; } 

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