问题描述
我正在尝试使用Firebase ML套件独立API读取条形码128和QR码。我能够读取条形码和QR码。但是,如果我的条形码长度超过30-35个字符,则条形码扫描仪将无法检测到条形码。我能够检测到QR码,但无法检测到条形码。
这是我的代码:
// Use this dependency to use the dynamically downloaded model in Google Play Services
implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:16.1.2'
implementation 'com.google.mlkit:barcode-scanning:16.0.3'
ScannerActivity:
executor = Executors.newSingleThreadExecutor();
PreviewView previewView = findViewById(R.id.cameraPreviewView);
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
Preview preview = new Preview.Builder().build();
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();
preview.setSurfaceProvider(
previewView.createSurfaceProvider());
ImageCapture imageCapture = new ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build();
ImageAnalysis imageAnalysis =
new ImageAnalysis.Builder()
.build();
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(this),new ImageAnalysis.Analyzer() {
private BarcodeScanner scanner = buildBarCodeScanner();
@Override
public void analyze(ImageProxy imageProxy) {
@SuppressLint("UnsafeExperimentalUsageError") Image mediaImage = imageProxy.getImage();
if (mediaImage != null) {
InputImage image =
InputImage.fromMediaImage(mediaImage,imageProxy.getImageInfo().getRotationDegrees());
Task<List<Barcode>> result = scanner.process(image);
result.addOnSuccessListener(new OnSuccessListener<List<Barcode>>() {
@Override
public void onSuccess(List<Barcode> barcodes) {
processBarCodes(barcodes);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Task failed with an exception
Log.i("CameraXApp3","scanner task failed. Error:" + e);
}
}).addOnCompleteListener(new OnCompleteListener<List<Barcode>>() {
@Override
public void onComplete(@NonNull Task<List<Barcode>> task) {
mediaImage.close();
imageProxy.close();
}
});
}
}
private BarcodeScanner buildBarCodeScanner() {
BarcodeScannerOptions options =
new BarcodeScannerOptions.Builder()
.setBarcodeFormats(
Barcode.FORMAT_QR_CODE,Barcode.FORMAT_CODE_128)
.build();
return BarcodeScanning.getClient(options);
}
private void processBarCodes(List<Barcode> barcodes) {
for (Barcode barcode : barcodes) {
confirmCounter++;
if (confirmCounter >= CONFIRM_VALUE) {
confirmCounter = 0;
final Rect boundingBox = barcode.getBoundingBox();
final Point[] cornerPoints = barcode.getCornerPoints();
String rawValue = barcode.getRawValue();
int valueType = barcode.getValueType();
if (valueType == Barcode.TYPE_TEXT) {
toast(MainActivity.this,"Received Message:" + rawValue);
}
}
}
}
public void toast(final Context context,final String text) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> Toast.makeText(context,text,Toast.LENGTH_LONG).show());
}
});
Camera camera = cameraProvider.bindToLifecycle(
((LifecycleOwner) this),cameraSelector,preview,imageCapture,imageAnalysis);
} catch (InterruptedException | ExecutionException e) {
}
},ContextCompat.getMainExecutor(this));
我还试图通过单击来增加焦点,但是没有运气:
previewView.setOnTouchListener((v,event) -> {
v.performClick();
if (event.getAction() == MotionEvent.ACTION_UP) {
final MeteringPointFactory factory = previewView.getMeteringPointFactory();
final MeteringPoint point = factory.createPoint(event.getX(),event.getY());
final FocusMeteringAction action = new FocusMeteringAction.Builder(point).build();
camera.getCameraControl().startFocusAndMetering(action);
return false;
}
return true;
});
解决方法
ML Kit条形码要求最细的条形至少为3像素宽。代码128中的每个字符为11 bar宽,因此就像素而言为33像素宽,而对于35个此类字符而言,其宽度需要1155像素。因此,条形码在图像中的宽度至少应为1155像素。粗略的计算会忽略+ +字符。
您可能需要提高此格式的图像分辨率。