Google 视觉:setRequestPreviewSize 无效

Google Vision: setRequestPreviewSize no effect

我正在使用 Google Vision API 开发带有嵌入式 QR 码扫描仪的 Android 应用程序。扫描仪功能正常,但用作相机预览的 SurfaceView 被垂直拉伸。不同仿真设备失真程度不同

据我了解,您将使用 mCameraSource.setRequestedPreviewSize(w,h) 来设置正确的大小。 wh我分别设置为Resources.getSystem().getDisplayMetrics().widthPixelsResources.getSystem().getDisplayMetrics().heightPixels。但是,我注意到无论我将什么数字解析为宽度和高度,它的显示方式都没有变化。

但是,调整显示它的 SurfaceView 的大小确实会对失真产生影响。对于一个特定的模拟 Android 设备,我可以静态设置正确的宽度和高度。然而,对于不同的设备,像素 w:h 比例略有不同,失真会变得相当大。

我在 Whosebug 上阅读了各种解决方案,但大多数使用 CameraPreview 而不是 CameraSource.Builder

到目前为止我的代码是(ScannerActivity.java 的一部分):

private SurfaceView svCamera;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;

@Override

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_scanner);
    initViews();
    initListeners();

    barcodeDetector = new BarcodeDetector.Builder(this)
                .setBarcodeFormats(Barcode.QR_CODE)
                .build();


    cameraSource = new CameraSource.Builder(this, barcodeDetector)
                .setRequestedPreviewSize(Resources.getSystem().getDisplayMetrics().widthPixels,     Resources.getSystem().getDisplayMetrics().heightPixels)
                .setAutoFocusEnabled(true)
                .build();

    svCamera.getHolder().addCallback(new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder surfaceHolder) {
        requestPermission();
        try {
                if (ActivityCompat.checkSelfPermission(ScannerActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                   return;
                }
                cameraSource.start(svCamera.getHolder());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
         @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

        }
         @Override
        public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
            cameraSource.stop();
        }
    });

   barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
       @Override
        public void release() {
            scanned = true;
        }
         @Override
        public void receiveDetections(Detector.Detections<Barcode> detections) {
              ...
        }
    });
} }   

谁能帮我设置预览大小?


我修复它的方式 在 Alex Cohn 的回答的帮助下:

DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int width = displayMetrics.widthPixels;    
int height = displayMetrics.heightPixels;
...
cameraSource.setRequestedPreviewSize(1280, 720); // Hardcoded, for now.

然后我将 SurfaceView 的大小设置为:

svCamera.setLayoutParams(new RelativeLayout.LayoutParams(width, width/9*16));

如果我记得的话,我会将其更新为非硬编码版本。

恰恰相反。您不能为 setRequestedPreviewSize() 选择任意分辨率。这个 CameraSource API 包裹了普通的相机 API,它只暴露了一些 "supported" 对宽度和高度。

如果您想显示不失真的实时取景,您必须设置 SurfaceView 以匹配所选相机预览的宽高比。这意味着,可以为 640x480 的相机使用 320x240 像素的表面。 1920x1080 的相机甚至可以使用 1280x720 的表面。

但是如果你有 800x480 的表面用于 1280x720 的相机(如果你的设备支持这样的相机分辨率),图片会稍微拉伸。