简体   繁体   English

Android zxing - 人像摄像头预览/ surfaceview拉伸/扭曲

[英]Android zxing - portrait camera preview/surfaceview is stretched/warped

I have managed to use the answer here to rotate the camera preview to portrait: http://code.google.com/p/zxing/issues/detail?id=178#c46 我已设法使用此处的答案将相机预览旋转为肖像: http//code.google.com/p/zxing/issues/detail?id = 178#c46

however the preview itself is stretched/warped - the height appears to be stretching to fill the box (but it could be that the width is too large for the screen and it is being squished to fit) 然而,预览本身是拉伸/扭曲的 - 高度似乎是拉伸以填充框(但可能是宽度对于屏幕来说太大而且它被压扁以适应)

Is there any way to 'wrap' the content rather than make it stretch to fit the surfaceview? 有没有办法“包装”内容而不是让它拉伸以适应表面视图?

EDIT: I sorted it by altering the 'findBestPreviewSizeValue' method in the 'CameraConfigurationManager' and reversing the X and Y points (thanks to sean owen for the pointer below!), here is the code: 编辑:我通过改变'CameraConfigurationManager'中的'findBestPreviewSizeValue'方法并反转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;
}

You have to do a fair bit more to get this to work than just set the preview to portrait mode. 除了将预览设置为纵向模式之外,您还需要做更多工作才能使其工作。 For example, you need to choose an appropriate preview size now that it's in portrait, not landscape. 例如,您需要选择适当的预览尺寸,因为它是纵向而非横向。

Wrapping is surely not desirable? 包装肯定不可取吗? No you can't make it wrap; 不,你不能让它包裹; it will always fling the whole preview image onto the SurfaceView , stretching if needed. 它总是将整个预览图像投射到SurfaceView ,如果需要可以拉伸。 I suppose you could reimplement a lot of that code to do something different, but it would be quite hard. 我想你可以重新实现很多代码来做一些不同的事情,但这会很难。

I had the same problem but I could resolved it by inverting the aspect ratio on the CameraConfigurationManager.java file inside the findBestPreviewSizeValue changing this 我有同样的问题但我可以通过反转findBestPreviewSizeValue中CameraConfigurationManager.java文件的宽高比来解决它

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

to this 对此

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

I found the solution here. 我在这里找到了解决方案。

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

You can get Priview size by this function: 您可以通过此功能获得Priview尺寸:

private List mSupportedPreviewSizes = parameters.getSupportedPreviewSizes(); private List 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);
            }

I managed to get this to work by changing below code in CameraConfigurationManager.java : 我设法通过更改CameraConfigurationManager.java以下代码来实现此CameraConfigurationManager.java

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

To: 至:

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

AND

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

TO: 至:

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

I did this alongside this post: Zxing Camera in Portrait mode on Android 我在这篇文章中做到了这一点: 在Android上的纵向模式中的Zxing Camera

Hope this helps others. 希望这有助于其他人。

The reason of deformation may is that the camera's preview aspect ratio does not match the display's aspect ratio. 变形的原因可能是相机的预览宽高比与显示器的宽高比不匹配。

Most aspect ratio of cellphone screen is 4:3, such as 2560x1440, 1920x1080 and so on. 手机屏幕的最大宽高比为4:3,如2560x1440,1920x1080等。 When you use parameter.setPreviewSize(width,height) to set camera preview dimension, if the value of height : width does not equals your phone screen's aspect ratio,the picture of camera will be deformed to fill thg screen. 当您使用parameter.setPreviewSize(width,height)设置相机预览尺寸时,如果height:width的值不等于您的手机屏幕的宽高比,相机的图片将变形以填充屏幕。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM