Обзор JavaScript-сканнеров штрихкодов

    Недавно появилась идея сэкономить на ТСД на складе и попробовать использовать вместо них обычные дешёвые мобильники (даже без пылезащиты). Интерфейс планирую реализовать в виде веб-приложения (обычные веб-странички, HTML + CSS + JS).

    Для того, чтобы всё получилось, необходимо научить веб-странички сканировать штрихкода через камеру телефона. Получить данные с камеры достаточно просто. Основная работа состоит в обработке кадра. Под катом обзор существующих готовых решений и много картинок.



    quaggaJS


    Ссылки:


    В результатах поиска — это первый вариант. Библиотека оснащена алгоритмом поиска штрихкода на картинке. Поддерживает одномерные штрихкоды: EAN, CODE 128, CODE 39, EAN 8, UPC-A, UPC-C, I2of5, 2of5, CODE 93, CODABAR. Поддерживает установку через NPM или Bower. Интерфейс библиотеки состоит из одного объекта «Quagga», содержащего 7 методов, всё достаточно просто.

    На сайте проекта присутствует страничка, где можно загрузить образцы и попробовать библиотеку в деле. Пробуем образец №1. Необходимо указать некоторые настройки, ок, не вопрос.


    В результате запуска определить штрихкод не удалось, но расположение штрихкода определено неплохо.

    Пробуем образец №2. Как-то безрадостно.



    Пробуем изменить настройки — поставить «Patch-Size» --> «Large». Нет. Правильный результат даёт, если поставить `Resolution (long side) = 800px`. Однако в действительности наибольшая сторона 640 пикселей.



    Возможно он лучше работает с картинками высокого разрешения. Хорошо, делаем третий образец (образец №3).



    Честно говоря я не знаю какой это тип штрихкода и попробовал все настройки — ШК не определился. Хорошо, давайте попробуем ещё один образец высокого разрешения (образец №4):



    Почему-то ни с какими настройками результата добиться не удалось.

    Попробуем «чистый» образец от следующей библиотеки (образец №5):



    Этот распознался.

    javascript-barcode-reader


    Ссылки:


    Это вторая в выдаче библиотека. Знает форматы: Code128 (UCC/EAN-128), Code93, Code39, Standard/Industrial 2 of 5, Interleaved 2 of 5, Codabar, EAN-13. Поддерживает установку через NPM, или можно просто подключить вот так:

    <script src="//unpkg.com/javascript-barcode-reader/dist/javascript-barcode-reader.min.js"></script>
    

    Или можно скачать всего один файлик: javascript-barcode-reader.min.js размером 10 445 байт.

    У проекта есть страничка с примерами, однако картинки получены путём генерации кодов, а не с камеры. Нам такое не пойдёт.

    Код для тестирования библиотеки
    barcode-scan.html
    <html>
    <head>
        <meta http-equiv="content-language" content="ru" />
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script src="//unpkg.com/javascript-barcode-reader/dist/javascript-barcode-reader.min.js"></script>
        <script type="text/javascript" src="barcode-scan.js"></script>
    </head>
    <body onload='onLoadPage()'>
        <img id="img1" src="scan02.png" />
    </body>
    </html>
    

    barcode-scan.html

    function onLoadPage() {
        Image = document.getElementById('img1');
        
        javascriptBarcodeReader(
          Image /* Image ID || HTML5 Image || HTML5 Canvas || HTML5 Canvas ImageData || Image URL */,
          {
            barcode: 'EAN-13', // 'Code-39'
            type: 'industrial', // задаётся для типа "Code-2of5", может быть "industrial" или "Interleaved"
          }
        )
          .then(code => {
            console.log(code)
          })
          .catch(err => {
            console.log(err)
          });
    }
    



    Образец №1. Библиотека выдаёт в консоль «Error: Failed to extract barcode!».
    Образец №2. Библиотека выдаёт в консоль «Error: Failed to extract barcode!».
    Образец №3. Библиотека выдаёт в консоль «Error: Failed to extract barcode!».
    Образец №4. Библиотека выдаёт в консоль «601».

    Хмм… может библиотека подключена неправильно? Попробуем вот такой образец:



    Образец №5. Библиотека выдаёт в консоль «10023». Прикольно.

    Dynamsoft Barcode Reader


    Сайт проекта
    Ядро библиотеки написано на WebAssembly (WASM) и только обёртки на JavaScript, что не так интересно. Знает форматы:

    1D: Code 39, Code 93, Code 128, Codabar, EAN-8, EAN-13, UPC-A, UPC-E, Interleaved 2 of 5 (ITF), Industrial 2 of 5 (Code 2 of 5 Industry, Standard 2 of 5, Code 2 of 5), ITF-14;

    2D: PDF417, QR Code, DataMatrix, Aztec.

    Это платная библиотека, доступна по подписке, все типы штрихкодов стоят 2199$ в год, если только одномерные коды, то стоимость уменьшается до 1099$ в год. Есть страничка1 и страничка2 для экспериментов.

    Образец №1. Да! Ответ правильный. Область обведена достаточно чётко.



    Образец №2. Да. Ответ снова правильный. Область тоже обведена достаточно чётко.



    Образец №3. Теперь мы знаем тип этого штрихкода.



    Образец №4. Ответ тоже верный.



    А ещё, судя по всему, можно вот так:



    Однако первый образец распознан с ошибкой. И попробуем ещё вот так (оригинал картинки очень размыт):



    Теперь мы знаем, что существует хотя бы одна работающая библиотека, хоть и платная.

    tobytailor get_barcode_from_image.js


    Ссылки:


    Простая маленькая библиотека. Знает только один формат штрихкодов: UPC. Если к коду такого типа вначале дописать ноль, то получится EAN-13.

    Пробуем первый образец:



    Результат: 000204892734. Образец распознан.

    Берём образец №2 (EAN-13). Только чтоб заработало, необходимо строку 32 скрипта написать так:

    ctx.drawImage(img, 0, 0, width, height); // было так: ctx.drawImage(img, 0, 0);
    

    Результат: XXXXXXXXXXXX. Образец не распознан.

    Берём следующий:



    Результат: XXXXXXXXXXXX. Не распознан.

    Давайте попробуем что-то простое:



    Результат: не распознан. Возможно ему нужно подавать так, чтобы кроме штрихкода на картинке ничего не было, исключая и лишнее пространство.



    Результат: 022334545453.

    И ещё один EAN-13:



    Частично распознан.

    EddieLa BarcodeReader


    GitHub
    Ещё одна бесплатная библиотека, с небольшим обращением от автора:
    If you like and/or use this project for commercial purposes consider donating to support my work.

    Если вам нравится и/или вы используете этот проект в коммерческих целях, рассмотрите возможность пожертвования для поддержки моей работы.
    Знает форматы: Code128, Code93, Code39, Standard/Industrial 2 of 5, Interleaved 2 of 5, Codabar and EAN-13. Имеет страницу для экспериментов.

    Образец №1. Область и тип определены верно. Код распознался с ошибкой.



    Образец №2. Хороший результат. Правильно распознаны: область, тип штрихкода и сам штрихкод.



    Образец №3. Отрицательно. Под углом не умеет.



    Образец №4. Очень хорошо, образец распознан.



    Образец №5. Образец распознан.



    Ну что ж, похвально. Последние изменения в библиотеке произошли 3 года назад.

    WebCodeCamJS


    Ссылки:


    Бесплатная библиотека (лицензия MIT). Знает следующие типы одномерных штрихкодов: Code-128, Code-93, Code-39, Codabar, EAN-13. Умеет распознавать QR-коды. На странице проекта есть возможность попробовать библиотеку.

    Образец №1: Не распознан.



    Образец №2: Распознан правильно.



    Образец №3: Не распознан.
    Образец №4: Не распознан.
    Образец №5: Распознан правильно.



    Возможность распознавать QR-коды представляется интересной, поэтому мной было собрано 6 образцов для тестирования этой и последующих библиотек:



    Образец №1: ничего.
    Образец №2: Ничего.
    Образец №3: Ничего.
    Образец №4: Ничего.
    Образец №5: Ничего.
    Образец №6: Распознан.



    Web QR


    Страница проекта
    Бесплатная библиотека. Заявлена генерация и распознавание QR-кодов. На странице проекта есть возможность попробовать библиотеку.

    Ни один из шести образцов не был распознан. На странице есть генератор QR-кодов, вот полученные с помощью этого генератора коды распознаются.



    UPD. Совместными усилиями в комментариях (спасибо TiesP ) удалось установить, что алгоритм работает, просто не умеет определять ориентацию кода. С учётом этого новые результаты такие:
    Образец №1 — не распознан.
    Образец №2 — не распознан.
    Образец №3 — не распознан.
    Образец №4 — не распознан.
    Образец №5 — распознан.
    Образец №6 — распознан.


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


    Итог


    Это всё что я нашёл. Находил несколько реализаций, основанных на одной из вышеприведённых, например вот эта. Повторю, что основной критерий поиска — это вся работа должна выполняться на клиентской стороне через браузер и без дополнительной установки чего либо. То есть решение должно быть реализовано на JavaScript и/или Wasm (поэтому ZBar не подходит).

    Если вам известна библиотека, отвечающая данным требованиям, и отсутствующая в статье — просьба сообщить.

    Полученный рейтинг библиотек таков:



    Статья состоялась благодаря интернет-магазину освещения Дивайн Лайт.
    Поддержать автора
    Поделиться публикацией

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 26

      0
      Вот этой вроде нет у вас — jsqrcode
        0
        Спасибо.
        Увы есть — это WebQR.
          0
          Странно, так плохо сработала. Я как-то на чеках с двумерным ШК проверял — почти все удалось распознать. Некоторые не с первого раза — надо было приближать и т.д. Но единичные не распознались
            0
            Наверное это потому, что с камеры идёт поток кадров и на вход алгоритма поступает много образцов и раз в сколько-то кадров звёзды сходятся.
              0
              Нет, я тестировал с помощью подключения библиотеки. Ей передавалось одно фото с телефона.
                0
                Хм… а каков был характер фото? На фото было видно что-то кроме QR-кода? Может быть остались примеры посмотреть?
                  +1
                  Вот один из примеров
                    0
                    Спасибо за пример!

                    Я всё понял — этот алгоритм не определяет ориентацию кода! Когда Вы прислали свой пример, я понял, что он снят при вертикальном положении камеры. И я попробовал развернуть один из своих образцов (положил на бок) и тот распознался! Нужно готовить обновление статьи.


        0
          0
          Можно попробовать Cordova/PhoneGap еще как вариант:
          github.com/phonegap/phonegap-plugin-barcodescanner
            0
            Если я правильно понимаю, эта библиотека требует установки специального компонента на ОС устройства. А значит это не JS-сканнер.
            Supported Platforms
            • Android
            • iOS
            • Windows (Windows/Windows Phone 8.1 and Windows 10)
            • Browser

            Note: the Android source for this project includes an Android Library Project. plugman currently doesn't support Library Project refs, so its been prebuilt as a jar library. Any updates to the Library Project should be committed with an updated jar.

            Note: Windows 10 applications can not be build for AnyCPU architecture, which is default for Windows platform. If you want to build/run Windows 10 app, you should specify target architecture explicitly, for example (Cordova CLI):

            cordova run windows — --archs=x86
              0
              С Cordova код приложения получается на JS, а плагины это обёртки над нативным кодом.
              Есть какое-то требование использовать именно JS для распознавания?
            +2
            Ждем Shape Detection API :)
            Он пока закрыт за флагом в Chrome, но вроде ожидается в Chrome 74
              0
              Интересная фича. Я об этом не знал.

              В настоящее время мы работаем над этим проектом. Мы будем обновлять этот пост по мере того, как этот новый API переходит от проектирования к реализации.

              ...

              … например, для создания считывателя QR-кода, они должны были полагаться на внешние библиотеки JavaScript. Это может быть дорого с точки зрения производительности и увеличивает размер страницы. С другой стороны, операционные системы, включая Android, iOS и macOS, а также аппаратные микросхемы, присутствующие в модулях камеры, обычно уже имеют производительные и высоко оптимизированные реализации таких функций (такие как Android FaceDetector или детектор универсальных функций iOS CIDetector).

              Shape Detection API — использует эти собственные реализации и предоставляет наборы их JavaScript-интерфейсов. На данный момент реализованы следующие функции: FaceDetector interface — обнаружение лица, BarcodeDetector interface — обнаружение штрихкода, TextDetector interface — обнаружение текста (OCR — оптическое распознавание текста).

              Примечание. Функция обнаружения текста, несмотря на то, что это интересное направление, ещё не работает достаточно стабильно через любую платформу и для всех наборов символов, чтобы быть стандартизованной. Поэтому данная функция перенесена в отдельную информационную спецификацию.

              Текущий статус: создано обоснование, всё остальное в процессе.

              Примечание. Планируется, что пробная версия будет доделана к выпуску Chrome 74. Также планируется, что API будет отключен, пока мы объединяем отзывы разработчиков. Вы всегда можете использовать Shape Detection API для локальных экспериментов, включив флаг enable-experimental-web-platform-features.

              Интерфейсы всех трех детекторов, FaceDetector, BarcodeDetector и TextDetector, очень похожи…

              Обратная связь
              Нам нужна ваша помощь, чтобы убедиться, что API-интерфейс Shape Detection полностью отвечает вашим потребностям и что мы не пропустили ни одного ключевого сценария.
              Если есть какая либо проблема, пожалуйста, сообщите о ней в репозитории Shape Detection API и предоставьте как можно больше подробностей.

              Нам также интересно знать, как вы планируете использовать данный функционал:
              У вас есть идеи по поводу варианта использования?
              Планируете ли вы вообще это использовать?
              Нравится этот функционал, и хочешь проявить свою поддержку?
              Поделитесь своими мыслями по поводу Shape Detection API здесь.


              Будем знать.
              0
              А с чего ZBar не подходит? Его в Wasm можно собрать, работает как зверь.
                –1
                Интересно, что мешает скачать все файлы библиотеки Dynamsoft Barcode Reader (включая файлы wasm), допустим с их онлайн демо, и использовать ее без лицензии?
                  0
                  Я думаю, что нарушение лицензии и мешает. Правда, не всем.
                  +1
                  Здесь ещё ZXing есть, но для меня я использую jsQR, который только QRCode может читать.
                    0

                    Это же ужасное юзабилити. Вы предствьте работника который мучается с таким софтом — нажалкнопку сделать фотку, сделал фотку, ему — "не распознано", повторяет и т.п. Именно поэтому в нормальных устройствах сделано так что юзер наводит дивайс и крутит/вертит его пока дивайс не распознает, о чем бибикнет и т.п. Если уж делать софтово то только по такому же принципу — то есть вместо фотки, открывается компонент в котором видеопоток с камеры и реал-тайм распознавание. Иначе это полный провал в юзабилити и соотв. производительности труда — вы предствьте какую-нибудь инвентаризацию — когда надо ходить и щелкать подряд сотни и тысячи баркодов.
                    Вывод — заменить ТСД можно, но придется писать софт или использовать специализированный браузер! Да есть такие решения(Enterprise Browser и т.п. — каждый называет по-разному). Это когда браузер сразу имеет встроенные АПИ для того же распознавания баркодов — то есть из джавасрипта сайта просто дергается нужное АПИ и открывается компонент с нормальным распознаванием в реальном-времени и показом потока с камеры. Кроме того могут быть и другие АПИ для функционала недоступного из браузера. Наша компания предлагает такой браузер, но в принципе можно собрать и самому на базе Кордовы/ФонГапа — собрать простое приложение с добавлением нужных екстеншенов.
                    На чистом предустановленном браузере пока ничего юзабельного не сделать.
                    Очень советую тестировать кейсы работников — типа взяли нормальный ТСД и отсканировали 10 коробок, потом взяли ваше решение и повторили. Потом сравниваем время и т.п. Я не думаю что возможно переплюнуть ТСД(в нормальных и подсветка области распознавания и само распознавание очень хорошее и быстрое + наличие специальных удобных кнопок типа курка и т.п. — короче там все продумано с точки зрения юзабилити), но к этому надо стремиться.

                      0
                      Мне кажется Вы поспешили с выводами: всё что изображено выше — это демо-страницы библиотек. В результате написания статьи ни один работник не пострадал )
                      Чтобы это заработало на страничке — не требуется никакого софта или специализированного браузера. У меня, например, как только попадает фокус на поле, в которое требуется вводить штрихкод, появляется изображение с камеры (видеопоток) с наложенным прицелом (узкая полоска посередине). Можно отказаться от сканирования, а можно навести камеру на штрихкод — и его значение попадёт в поле ввода и изображение с камеры пропадает. Подсветка в наличии.
                      Переплюнуть ТСД никто не пытается. Это эксперимент с целью как раз установить, насколько конкретно это решение хуже ТСД. Я исхожу из того, что при относительно большом интервале между сканированиями, увеличение времени на одно сканирование, скажем в полтора раза, общее время работы увеличит незначительно.
                        0

                        Да я немного отстал от жизни — посмотрел что есть вполне себе нормально работающие реал-тайм решения на JS(по крайней мере на моей айфоне :-) ). Мы просто уж давно разрабатываем гибридное решение типа Кордовы(но круче :-) ) и соотв. уже давно поддерживаем екстеншены с оттопыриванием API в JS, но само распознавание нативное конечно + поддержка СДК вендоров на ТСД. ТСД конечно не просто так денег стоят. Сейчас есть дальнобойные они спокойно с 1-2 метров распознают и лазерная подсветка прицела есть и т.п. Проблема с ТСД то что они ОЧЕНЬ долго служат и сейчас еще много компаний имеет парк WinCE дивайсов.

                      0
                      надо смотреть, что приходит с камеры в код. очень печально всё было, когда я со Смарта читал на сайте коды (qr в частности) и на сервер из браузера приходили то сжатые, то растянутые фото, поэтому тяжко было определять… нативный код/библиотеки на том же Андроиде работает в разы лучше, как платная версия из статьи
                        0
                        А я так и не понимаю, зачем таскать кучу картинок на сервер, если их можно обрабатывать на клиенте.
                          0
                          и это правильно, но что так, что так — пока нет бесплатного хорошего считывателя через media браузера из-за искажения, нужна доп. обработка… wasm версию не пробовал, может взлетела бы (хотя первоначально проблема на уровне источника данных)
                          посмотрим, что нам в хроме завезут. должно нормально работать, по идее
                            0
                            Не знаю, я пробовал получать видеопоток на разных браузерах, с разных устройств — искажения нет.
                            Вот основные функции для работы с камерой, которые я использую, пользуйтесь на здоровье (здесь ещё подсветка включается, если нужно):
                            Основные функции для работы с камерой
                            function camera_init() {
                            
                                var constraints = {video: true};
                                deviceId = cookieGet('cameraId');
                                
                                if (deviceId != undefined) {
                                    constraints = { 
                                        video : { 
                                            deviceId: { exact: deviceId }                 
                                        } 
                                    };
                                    navigator.mediaDevices.getUserMedia(constraints)
                                        .then(on_videostream_success)
                                        .catch(on_videostream_error)
                                    ;
                                }else{
                                    alert('Зайдите в настройки и укажите какую камеру использовать.');
                                }
                                
                            }
                            
                            function on_videostream_success(stream) {
                            
                                const track = stream.getVideoTracks()[0];
                                g_barcodescan_track = track;
                            
                                video.addEventListener('loadedmetadata', (e) => {  
                                  window.setTimeout(() => (
                                    onCapabilitiesReady(track.getCapabilities())
                                  ), 500);
                                });
                                
                                function onCapabilitiesReady(capabilities) {
                                
                                    cameraLight = cookieGet('cameraLight') == 'on';
                                
                                    var constraints = {
                                          advanced: [{
                                                torch: cameraLight
                                            }]
                                        };  
                                    
                                    if (capabilities.torch) {
                                        track.applyConstraints(constraints)
                                            .catch(e => console.log(e));
                                    }
                                    
                                    g_barcodescan_video.play();
                                    BarcodeJob();
                            
                                }
                                
                                g_barcodescan_video.srcObject = stream;
                            
                            }
                            


                              0
                              А по поводу хромовского BarcodeDetector — вполне может оказаться, что это API к встроенному в устройство аппаратному сканеру (как в ТСД-шках). В пользу этого говорит вот это:
                              а также аппаратные микросхемы, присутствующие в модулях камеры, уже имеют производительные и высоко оптимизированные реализации таких функций


                              Я пробовал на разных устройствах включать в браузере этот флаг и пробовал API BarcodeDetector, и неизменно получал две ошибки, либо
                              Barcode Detection failed: Barcode detection service unavailable.

                              либо

                              … device unavailable.

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                        Самое читаемое