Google 视觉:setRequestPreviewSize 无效
Google Vision: setRequestPreviewSize no effect
我正在使用 Google Vision API 开发带有嵌入式 QR 码扫描仪的 Android 应用程序。扫描仪功能正常,但用作相机预览的 SurfaceView 被垂直拉伸。不同仿真设备失真程度不同
据我了解,您将使用 mCameraSource.setRequestedPreviewSize(w,h)
来设置正确的大小。 w
和h
我分别设置为Resources.getSystem().getDisplayMetrics().widthPixels
和Resources.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 的相机(如果你的设备支持这样的相机分辨率),图片会稍微拉伸。
我正在使用 Google Vision API 开发带有嵌入式 QR 码扫描仪的 Android 应用程序。扫描仪功能正常,但用作相机预览的 SurfaceView 被垂直拉伸。不同仿真设备失真程度不同
据我了解,您将使用 mCameraSource.setRequestedPreviewSize(w,h)
来设置正确的大小。 w
和h
我分别设置为Resources.getSystem().getDisplayMetrics().widthPixels
和Resources.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 的相机(如果你的设备支持这样的相机分辨率),图片会稍微拉伸。