Android zxing – предварительный просмотр камеры / просмотр поверхности растянут / искажен

Мне удалось использовать здесь ответ, чтобы повернуть предварительный просмотр камеры на портрет: http://code.google.com/p/zxing/issues/detail?id=178#c46

Однако сам предварительный просмотр растягивается / деформируется – высота, по-видимому, растягивается, чтобы заполнить поле (но может быть, что ширина слишком велика для экрана, и она сжимается, чтобы соответствовать)

Есть ли способ «обернуть» контент, а не сделать его растянутым, чтобы соответствовать просмотру поверхности?

EDIT: я отсортировал его, изменив метод findBestPreviewSizeValue в «CameraConfigurationManager» и изменив точки X и Y (спасибо sean owen за указатель ниже!), Вот код:

private static Point findBestPreviewSizeValue(CharSequence previewSizeValueString, Point screenResolution) { int bestX = 0; int bestY = 0; int diff = Integer.MAX_VALUE; for (String previewSize : COMMA_PATTERN.split(previewSizeValueString)) { previewSize = previewSize.trim(); int dimPosition = previewSize.indexOf('x'); if (dimPosition < 0) { Log.w(TAG, "Bad preview-size: " + previewSize); continue; } int newX; int newY; try { newY = Integer.parseInt(previewSize.substring(0, dimPosition)); newX = Integer.parseInt(previewSize.substring(dimPosition + 1)); //original: //newX = Integer.parseInt(previewSize.substring(0, dimPosition)); //newY = Integer.parseInt(previewSize.substring(dimPosition + 1)); } catch (NumberFormatException nfe) { Log.w(TAG, "Bad preview-size: " + previewSize); continue; } int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y); if (newDiff == 0) { bestX = newY; bestY = newX; //original: //bestX = newX; //bestY = newY; break; } else if (newDiff < diff) { bestX = newY; bestY = newX; //original: //bestX = newX; //bestY = newY; diff = newDiff; } } if (bestX > 0 && bestY > 0) { return new Point(bestX, bestY); } return null; } 

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

Обертка, конечно, нежелательна? Нет, вы не можете заставить его обернуть; Он всегда будет SurfaceView изображение предварительного просмотра на SurfaceView , растягивая при необходимости. Я полагаю, вы могли бы переопределить много этого кода, чтобы сделать что-то другое, но это было бы довольно сложно.

У меня была та же проблема, но я смог ее решить, инвертируя соотношение сторон в файле CameraConfigurationManager.java внутри findBestPreviewSizeValue, меняя это

  float screenAspectRatio = (float) screenResolution.x / (float) screenResolution.y; 

к этому

  float screenAspectRatio = (float) screenResolution.y / (float) screenResolution.x; 

Я нашел решение здесь.

http://bighow.net/4660010-Android_zxing___portrait_camera_preview_surfaceview_is_stretched_warped.html

Вы можете получить размер Priview с помощью этой функции:

Private Список mSupportedPreviewSizes = parameters.getSupportedPreviewSizes ();

 if (mSupportedPreviewSizes != null) { mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); } private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.1; double targetRatio = (double) h / w; if (sizes == null) return null; Camera.Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; for (Camera.Size size : sizes) { double ratio = (double) size.height / size.width; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Camera.Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } float ratio; if (mPreviewSize.height >= mPreviewSize.width) ratio = (float) mPreviewSize.height / (float) mPreviewSize.width; else ratio = (float) mPreviewSize.width / (float) mPreviewSize.height; after getting ratio set your size in protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension((int) (width * ratio), height); } 

Мне удалось заставить это работать, изменив ниже код в CameraConfigurationManager.java :

float screenAspectRatio = (float) screenResolution.x / (float) screenResolution.y;

Для того, чтобы:

 float screenAspectRatio = (float) screenResolution.y / (float) screenResolution.x; 

А ТАКЖЕ

 float aspectRatio = (float) maybeFlippedWidth / (float) maybeFlippedHeight; 

TO:

 float aspectRatio = (float) maybeFlippedHeight / (float) maybeFlippedWidth; 

Я сделал это рядом с этим сообщением: Zxing Camera в режиме Portrait на Android

Надеюсь, это поможет другим.

Причиной деформации может быть то, что соотношение сторон предварительного просмотра камеры не соответствует формату изображения.

Большинство форматов сотового телефона составляют 4: 3, например 2560×1440, 1920×1080 и так далее. Когда вы используете параметр parameter.setPreviewSize (ширина, высота), чтобы установить размер предварительного просмотра камеры, если значение высоты: ширина не равно пропорции экрана вашего телефона, изображение камеры будет деформировано для заполнения экрана.