Search code examples
androidsurfaceviewzxingportraitstretching

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

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:

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;
}

Solution

  • 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. I suppose you could reimplement a lot of that code to do something different, but it would be quite hard.