我正在使用Google Vision API开发带有嵌入式QR码扫描仪的Android应用程序。扫描仪功能正常,但充当相机预览的 SurfaceView 是垂直拉伸的。不同仿真设备的失真程度不同。
据我了解,您将使用mCameraSource.setRequestedPreviewSize(w,h)
来设置正确的大小。w
和h
我分别设置为Resources.getSystem().getDisplayMetrics().widthPixels
和Resources.getSystem().getDisplayMetrics().heightPixels
。但是,我注意到,无论我解析为宽度和高度的数字,它的显示方式都没有变化。
但是,调整显示它的 SurfaceView 的大小确实会对变形产生影响。对于一个特定的模拟Android设备,我可以静态设置正确的宽度和高度。但是,对于不同的设备,像素W:h比略有不同,失真可能会变得非常大。
我已经阅读了有关StackOverflow的各种解决方案,但是大多数都使用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()
选择任意分辨率。此CameraSourceAPI 包装了普通的 Camera API,该 API 仅公开一些"支持的"宽度和高度对。
如果要显示实时取景而不失真,则必须设置 SurfaceView 以匹配所选相机预览的纵横比。这意味着,可以将 320x240 像素的表面用于 640x480 的相机。对于1920x1080的相机,甚至可以使用1280x720的表面。
但是,如果您的表面为 800x480,相机为 1280x720(并且如果您的设备支持此类相机分辨率),则图片将略微拉伸。