【问题标题】:Android zxing - portrait camera preview/surfaceview is stretched/warpedAndroid zxing - 人像相机预览/surfaceview 被拉伸/扭曲
【发布时间】:2012-07-16 05:30:02
【问题描述】:

我已设法使用此处的答案将相机预览旋转为纵向: http://code.google.com/p/zxing/issues/detail?id=178#c46

但是预览本身被拉伸/扭曲 - 高度似乎被拉伸以填充框(但可能是宽度对于屏幕来说太大并且被挤压以适应)

有什么方法可以“包装”内容而不是使其拉伸以适应表面视图?

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

【问题讨论】:

  • 这段代码究竟做了什么?我该如何使用它?

标签: android surfaceview zxing portrait stretching


【解决方案1】:

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

大部分手机屏幕的宽高比是4:3,如2560x1440、1920x1080等。当您使用 parameter.setPreviewSize(width,height) 设置相机预览尺寸时,如果 height : width 的值不等于您手机屏幕的纵横比,相机的图片将变形以填满屏幕。

【讨论】:

    【解决方案2】:

    我设法通过更改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;
    

    我在这篇文章旁边做了这个:Zxing Camera in Portrait mode on Android

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

    【讨论】:

      【解决方案3】:

      你可以通过这个函数获取Priview大小:

      私有列表 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);
                  }
      

      【讨论】:

        【解决方案4】:

        我有同样的问题,但我可以通过反转 findBestPreviewSizeValue 中 CameraConfigurationManager.java 文件的纵横比来解决它

         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

        【讨论】:

        • 该链接与我上面提出的问题完全相同,实际上当您单击“查看完整的回复帖子”时链接到该问题
        【解决方案5】:

        除了将预览设置为纵向模式外,您还需要做更多的工作才能使其正常工作。例如,您需要选择合适的预览尺寸,因为它是纵向的,而不是横向的。

        包装肯定是不可取的吗?不,你不能让它包装;它总是将整个预览图像投射到SurfaceView,如果需要,可以拉伸。我想你可以重新实现很多代码来做一些不同的事情,但这会很困难。

        【讨论】:

        • 感谢您的快速回答 :) 您能否详细说明适当的预览尺寸?我从问题中的链接实现的代码更改似乎工作正常我以前似乎工作正常,他们扫描二维码/条形码没问题,实际上只是我的预览似乎被稍微拉伸/挤压
        • 在您提到设置适当的预览大小之后,我查看了 'findBestPreviewSizeValue' 方法,基本上交换了点的 X 和 Y 值并对其进行了排序:) 我会更新问题上面有代码,再次感谢指点!
        猜你喜欢
        • 1970-01-01
        • 2012-08-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-12
        相关资源
        最近更新 更多