Есть ли способ сканирования штрих-кодов в Flutter?

По сути, я делаю приложение, которое сканирует QR-код для подключения к серверу. Затем приложение отсканирует штрих-код продуктов, сделает снимки товара и отправит их на сервер. Мой вопрос заключается в следующем:

Существует ли плагин Flutter для сканирования QR-кодов и штрих-кодов, который не вступает в конфликт с image_picker?

Вот что я нашел до сих пор.

Я ценю любую помощь, которую вы можете оказать. Спасибо!


Обновить

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

Ответ 1

У меня раньше была похожая проблема, и после поиска, как и вы, я не нашел много. Я решил, что лучшим подходом было бы написать сам плагин... так что постыдный плагин для моего плагина здесь = D, не то чтобы я извлек выгоду из того, что кто-то еще его вообще использует.

Вы можете увидеть это здесь. Однако у меня не было времени документировать это, тщательно тестировать или публиковать в пабе должным образом. Так что ваш пробег может отличаться. Тем не менее, он должен работать на Android 4. 4+ (и, возможно, ниже), а также на устройствах iOS, которые поддерживаются. Я также не тестировал его в сочетании с плагином Camera, но не понимаю, почему с ним могут возникнуть проблемы.

Он использует другой подход, чем большинство других плагинов кода qr; вместо того, чтобы создавать окно Android или iOS, выполнять сканирование, а затем возвращаться к флаттеру, он использует возможности рендеринга текстур флаттера, чтобы камера рендерилась прямо в флаттер.

Еще несколько вещей, которые следует учитывать, это то, что он использует Google Mobile Vision SDK с соответствующими лицензиями и возможностями, которые прилагаются к нему (и требует последней версии Play Services на Android); и что в настоящее время он поддерживает только самое основное извлечение информации из сканирования штрих-кода - мне нужен был только необработанный текст, чтобы все, что я сделал.

Чтобы использовать это, добавьте это в ваш pubspec.yaml:

dependencies:
  qr_mobile_vision: '^0.0.7'

И реализовать следующим образом:

import 'package:qr_mobile_vision/QrCamera.dart';

...

new Container(
  constraints: new BoxConstraints.loose(
  new Size(cameraSize, cameraSize)),
  child: new QrCamera(
    qrCodeCallback: (code) {
      print(code);
    }
  ),
)

Я планирую закончить документацию/тестирование/и т.д. в конце концов, но вы можете попробовать это в то же время. Если вы решите использовать его и нуждаетесь в функции, которую он не поддерживает, я могу помочь в ее реализации... но PR приветствуются и поощряются!

ОБНОВЛЕНИЕ: теперь это включает поддержку штрих-кода. Вы можете указать, какие типы QR-кодов/штрих-кодов вы хотите поддерживать при создании экземпляра QrCamera. По умолчанию используется значение all, которое требует больше обработки, поэтому, если вам нужен определенный тип, рекомендуется передать его.

Ответ 2

Я работаю над тем, что в настоящее время является компаньоном моего плагина генерации QR (https://github.com/lukef/qr.flutter), но у меня нет конкретные сроки, к сожалению.

Мой план состоит в том, чтобы использовать объект Texture и подключить камеру (или использовать fork/использовать плагин камеры), а затем использовать API Google Vision (https://developers.google.com/vision/android/barcodes-overview).

Это должно быть прилично тривиально, мне просто нужно найти время. В любом случае, это был план, если вы хотите это сделать:)

Ответ 3

В проекте Flutter можно использовать SDK с открытым исходным кодом (например, ZXing) или коммерческий SDK (например, SDK ). Реализация функции сканирования штрих-кода проста.

Я написал статью - Программирование флаттера с файлом Android AAR, в котором говорится, как сканировать QR-код в проекте флаттера. исходный код также доступен на GitHub.

Java-код

private String onGetBarcode(String json) {
        String filename;
        try {
            JSONObject message = new JSONObject(json);
            filename = message.getString("filename");
        } catch (JSONException e) {
            Log.e(TAG, "JSON exception", e);
            return null;
        }

        String locationProvider;
        String barcodeResult = "No barcode detected";
        File file = new File(filename);
        if (!file.exists()) {
            barcodeResult = "No file exists: " + file.toString();
            Toast.makeText(BarcodeReaderActivity.this, barcodeResult, Toast.LENGTH_LONG).show();

            return null;
        }
        else {
            Bitmap bitmap = BitmapFactory.decodeFile(file.toString());
            BarcodeReader reader = new BarcodeReader("license");
            ReadResult result = reader.readSingle(bitmap, Barcode.QR_CODE);
            Barcode[] all = result.barcodes;
            if (all != null && all.length == 1) {
                barcodeResult = all[0].displayValue;
            }
            else {
                barcodeResult = "no barcode found: " + file.toString();
            }

            bitmap.recycle();

        }

        JSONObject reply = new JSONObject();
        try {
            if (barcodeResult != null) {
              reply.put("result", barcodeResult);
            } else {
              reply.put("result", "No barcode detected");
            }
        } catch (JSONException e) {
            Log.e(TAG, "JSON exception", e);
            return null;
        }

        return reply.toString();
    }

Код дротика

@override
  Widget build(BuildContext context) {
    if (_isExisted) {
      return new Material(
          child: new Center(
              child: new Column(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    new Text('Barcode Reader'),
                    new Input(
                      labelText: 'Please input the image path',
                      value: new InputValue(text: _filename),
                      onChanged: onTextChanged,
                      autofocus: true,
                    ),
                    new Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: <Widget>[
                          new RaisedButton(
                              child: new Text('Read'),
                              onPressed: _getBarcode
                          ),
                          new RaisedButton(
                              child: new Text('Reset'),
                              onPressed: _resetResult
                          ),
                        ]
                    ),
                    new Image.file(new File(_filename)),
                    new Text('$_result'),
                  ]
              )
          )
      );
    }
    else {
      return new Material(
          child: new Center(
              child: new Column(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    new Text('Barcode Reader'),
                    new Input(
                      labelText: 'Please input the image path',
                      onChanged: onTextChanged,
                      autofocus: true,
                    ),
                    new Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: <Widget>[
                          new RaisedButton(
                              child: new Text('Read'),
                              onPressed: _getBarcode
                          ),
                          new RaisedButton(
                              child: new Text('Reset'),
                              onPressed: _resetResult
                          ),
                        ]
                    ),
                    new Text('$_result'),
                  ]
              )
          )
      );
    }
  }

  Future<Null> _readBarcode() async {
    final Map<String, String> message = <String, String>{'filename':_filename};
    final Map<String, dynamic> reply = await HostMessages.sendJSON('getBarcode', message);
    // If the widget was removed from the tree while the message was in flight,
    // we want to discard the reply rather than calling setState to update our
    // non-existent appearance.
    if (!mounted)
    return;
    setState(() {
    _result = reply['result'].toString();
    });
  }

Скриншот

введите описание изображения здесь

Поймите немного времени и сделайте это сами:)