ML Kit Сканирование штрих-кода: неверный размер данных изображения - PullRequest
0 голосов
/ 16 мая 2018

Я хотел бы обнаружить штрих-код в захваченном изображении. Я снимаю изображение с помощью камеры Android2. После этого метаданные изображения извлекаются и изображение сохраняется на устройстве. Все метаданные передаются следующему действию, в котором приложение пытается обнаружить штрих-код.

Это следующее действие создает байт [] из ранее сохраненного файла. Затем соответствующие объекты 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<List<FirebaseVisionBarcode>> result = detector.detectInImage(image)

1 Ответ

0 голосов
/ 16 мая 2018

Несколько вещей.

  1. Ваш формат изображения не должен быть NV21, если вы используете камеру2. Смотрите здесь для всех поддерживаемых Camera2 форматов изображений: https://developer.android.com/reference/android/media/Image#getFormat() Ваш байт [] не является NV21, и вы указали IMAGE_FORMAT_NV21 и привели к ошибке

  2. Наиболее интуитивно понятная интеграция с камерой2, как показано ниже:

    • Укажите формат JPEG при создании экземпляра ImageReader.

    • onImageAvailable вернет вам android.media.Image, и вы можете напрямую использовать FirebaseVisionImage.fromMediaImage (...) для создания FirebaseVisionImage. (Вы можете найти, как вычислить информацию о ротации из официального документа здесь )

  3. Если вам нужно выполнить два действия, то вам нужно обойти тот факт, что android.media.Image не подлежит продаже. Я бы посоветовал вам сначала преобразовать его в растровое изображение, которое является Parcelable, и вы можете напрямую установить его в качестве дополнительного Intent (на ваше усмотрение. Просто подумав с точки зрения конечного пользователя, не часто можно видеть, как штрих-код сохраняется в моей галерее изображений. Таким образом, вы можете пропустить этап сохранения его в файл). Позже, во втором задании вы можете использовать FirebaseVisionImage.fromBitmap(...).

...