ZXing. JS-библиотека для сканирования штрихкодов.

barcode-upca

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

В комментариях к предыдущей статье было озвучено две полезных мысли:

  1. Библиотеку ZBar можно скомпилировать в Wasm, и что она работает хорошо.
  2. Я пропустил библиотеку ZXing, которая тоже работает хорошо.

Для ZBar после компиляции потребуется писать какую-то обёртку, а значит разбираться в её коде. Для интеграции ZXing в свой проект уже всё готово и я начал с неё. Забегаю вперёд, скажу, что библиотека работает великолепно — намного быстрее и точнее. Мои коллеги в восторге.

Итак, проект библиотеки (GitHub). Живой пример. Поддерживаемые типы кодов:

  • EAN8
  • EAN13
  • Code39
  • Code128
  • ITF
  • RSS-14
  • QR Code
  • Data Matrix
  • PDF 417

Использование

Самый простой набор действий такой. Сначала подключаем JS-модуль библиотеки. Можно использовать CDN-ссылку, можно скачать к себе:

<script type="text/javascript" src="https://unpkg.com/@zxing/library@latest"></script>

Далее добавляем на страничку компонент, в который будет выводиться видопоток:

<video id="video" ></video>

Далее добавляем JS-скрипт:

const codeReader = new ZXing.BrowserMultiFormatReader();
g_codeReader.decodeFromVideoDevice(cameraId, 'video', (result, err) => {
    if (result) {
        alert(result.text);            
    }
    if (err && !(err instanceof ZXing.NotFoundException)) {
        alert(err);
    }
});

Здесь:

  • cameraId — это УИД камеры, с которой будет поступать видеопоток.
  • "video" — это ID компонента на страничке, куда будет выводиться видеопоток.
  • result.text — содержит отсканированный код.
  • err — содержит текст ошибки. Как мы видим — всё достаточно просто.

Как определить cameraId

Логично иметь отдельную страницу с настройками. Там и нужно выводить список имеющихся на устройстве камер. Пользователь выбирает, какая его интересует и сохраняет настройки. Можно хранить в куках.

Вариант 1

function settings_onload() {

    if (!navigator.mediaDevices
        || !navigator.mediaDevices.enumerateDevices) {

        alert("enumerateDevices() not supported.");
        return;
    }

    try {
        navigator.mediaDevices.enumerateDevices()
            .then(settings_create_cameras_radiobutton);
    }catch(err){
        alert(err.name + ": " + err.message);
    }

}

function settings_create_cameras_radiobutton(devices) {

    for (var n = 0; n < devices.length; n++) {
        device = devices[n];
        if (device.kind == 'videoinput') {
            settings_add_camera_case(
                device.label
                ,device.deviceId
            );
        }
    }

}

Здесь функция "settings_add_camera_case" реализует добавление элемента списка камер. Первый аргумент — это название камеры, а второй — как раз её УИД.

Вариант 2

Также можно воспользоваться средствами компоненты:

codeReader.getVideoInputDevices()
    .then((videoInputDevices) => {
        const sourceSelect = document.getElementById('sourceSelect');
        selectedDeviceId = videoInputDevices[0].deviceId;
        if (videoInputDevices.length >= 1) {
            videoInputDevices.forEach((element) => {
                const sourceOption = document.createElement('option');
                sourceOption.text = element.label;
                sourceOption.value = element.deviceId;
                sourceSelect.appendChild(sourceOption);
        });
    }
}

Звук "Бип"

При успешном срабатывании можно добавить классический звук "Бип":

var beep = new Audio();
beep.addEventListener('loadeddata', function() { beep.play(); });    
beep.src = beepUrl;

Где beepUrl — это адрес к файлику со звуком.

Собственно всё.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *