Android zxing - 竖屏相机预览/ SurfaceView 变形或拉伸

18

我已经成功使用这里的答案将相机预览旋转到竖屏:http://code.google.com/p/zxing/issues/detail?id=178#c46

但是预览本身被拉伸/扭曲了 - 高度似乎在拉伸以填充框(但也有可能是宽度太大而被挤压以适应)

有没有办法“包裹”内容,而不是让它拉伸以适应SurfaceView?

编辑:我通过修改“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;
}

1
这段代码具体是做什么的?我该如何使用它? - Behzad
5个回答

6

要让此项工作正常运行,您需要进行更多操作,而不仅仅是将预览设置为纵向模式。例如,现在需要选择适当的预览尺寸,因为它已经处于纵向而不是横向。

换行肯定是不可取的吧?不能让它自动换行;它将始终将整个预览图像投放到SurfaceView上,并根据需要进行拉伸。我想你可以重新实现很多代码来做一些不同的事情,但这将是相当困难的。


1
谢谢您的快速回答 :) 您能详细说明适当的预览大小吗?我从问题链接中实施的代码更改似乎运行良好,我使用了扫描QR /条形码没有问题,只是我的预览似乎稍微被拉伸/压缩了。 - AndroidNoob
1
在你提到设置适当的预览大小后,我查看了“findBestPreviewSizeValue”方法,并基本上交换了点的X和Y值,这样就解决了:) 我将在上面更新问题的代码,再次感谢你的指引! - AndroidNoob

2

我曾碰到过相同的问题,但通过在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

那个链接与我上面提出的问题完全相同,实际上当您点击“查看带有回复的完整线程”时,它链接到这个问题。 - AndroidNoob

1
你可以使用以下函数获取预览尺寸:
私有列表 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);
            }

0

变形的原因可能是相机预览的宽高比与显示器的宽高比不匹配。

大多数手机屏幕的宽高比为4:3,例如2560x1440、1920x1080等。当您使用parameter.setPreviewSize(width,height)设置相机预览尺寸时,如果高度:宽度的值与您的手机屏幕宽高比不相等,则相机的图像将被拉伸以填满屏幕。


0

我通过更改CameraConfigurationManager.java中的以下代码,成功使其工作:

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

改为:

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

并且

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

致:

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

我在这篇文章的同时完成了这个项目:如何在Android上使用竖屏模式下的Zxing相机

希望能对其他人有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接