我想在捕獲的圖像中檢測條形碼。我使用android的camera2捕獲圖像。此后,將檢索圖像的元數據并將圖像保存到設備。元數據全部傳遞到下一個活動,該活動是應用程序嘗試檢測條形碼的地方。
下一個活動是從先前保存的文件創建一個byte []。接下來,使用隨意圖傳遞的數據創建相關的FirebaseVision對象。最后,應用程序嘗試調用detectInImage()方法,該方法會引發錯誤:
“java.lang.IllegalArgumentException:無效的圖像數據大小。”
我懷疑這是因為捕獲的圖像太大,但是我似乎無法弄清楚如何捕獲較小的圖像,并且在參考文檔中也找不到任何有關允許的最大尺寸的信息。非常感謝您提供有關此錯誤及其解決方法的信息。以下是我認為是相關的代碼。private final ImageReader.OnImageAvailableListener onImageAvailableListener
= new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader imageReader) {
try{
// Semaphore ensures date is recorded before starting next activity
storeData.acquire();
Image resultImg = imageReader.acquireNextImage(); // Image from camera
imgWidth = resultImg.getWidth();
imgHeight = resultImg.getHeight();
ByteBuffer buffer = resultImg.getPlanes()[0].getBuffer();
data = new byte[buffer.remaining()]; // Byte array with the images data
buffer.get(data);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
// Note: mediaFile directs to Pictures/"ThisProject" folder
File media = new File(mediaFile.getPath() +
File.separator + "IMG_" + timeStamp + ".jpg");
// Saving the image
FileOutputStream fos = null;
try {
fos = new FileOutputStream(media);
fos.write(data);
uri = Uri.fromFile(media);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
}
resultImg.close();
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage());
}
storeData.release();
}
};
這實際上是檢索圖像的高度和寬度,然后將其寫入文件。
發送到下一個活動的數據包括:圖像寬度,圖像高度,圖像旋轉和指向文件的Uri。
使用此工具,我嘗試使用Firebase ML Kit檢測條形碼:
// uri is the uri referencing the saved image
File f = new File(uri.getPath());
data = new byte[(int) f.length()];
try{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
DataInputStream dis = new DataInputStream(bis);
dis.readFully(data);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
FirebaseVisionBarcodeDetectorOptions options = new FirebaseVisionBarcodeDetectorOptions.Builder().setBarcodeFormats(
FirebaseVisionBarcode.FORMAT_QR_CODE,
FirebaseVisionBarcode.FORMAT_DATA_MATRIX
).build();
FirebaseVisionBarcodeDetector detector = FirebaseVision.getInstance().getVisionBarcodeDetector(options);
FirebaseVisionImage image;
int rotationResult;
switch (imgRotation) {
case 0: {
rotationResult = FirebaseVisionImageMetadata.ROTATION_0;
break;
}
case 90: {
rotationResult = FirebaseVisionImageMetadata.ROTATION_90;
break;
}
case 180: {
rotationResult = FirebaseVisionImageMetadata.ROTATION_180;
break;
}
case 270: {
rotationResult = FirebaseVisionImageMetadata.ROTATION_270;
break;
}
default: {
rotationResult = FirebaseVisionImageMetadata.ROTATION_0;
break;
}
}
FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
.setWidth(imgWidth)
.setHeight(imgHeight)
.setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
.setRotation(rotationResult)
.build();
image = FirebaseVisionImage.fromByteArray(data, metadata);
Task> result = detector.detectInImage(image)
最佳答案
一些東西。
如果使用camera2,則圖像格式不應為NV21。有關所有camera2支持的圖像格式,請參見此處:
https://developer.android.com/reference/android/media/Image#getFormat()
您的byte []不是NV21,并且您指定了IMAGE_FORMAT_NV21并導致錯誤
與camera2的最直觀的集成如下所示:
實例化ImageReader時指定JPEG格式。
onImageAvailable將帶給您android.media.Image,您可以直接使用FirebaseVisionImage.fromMediaImage(...)創建FirebaseVisionImage。 (您可以從官方文檔here中找到如何計算輪換信息)
如果必須執行兩個活動,則需要解決android.media.Image不可打包的事實。我建議您先將其轉換為可打包的位圖,然后將其直接設置為Intent extra(由您決定。僅從最終用戶的角度考慮,通常不會看到條形碼被保存到我的圖片庫中。
因此,您可能需要考慮跳過將其保存到文件的步驟。稍后,在第二活動中,您可以使用FirebaseVisionImage.fromBitmap(...)。