java генерация qr кода
Генерируем цветной QR-код с логотипом на Java
Некоторое время назад мне потребовалось генерировать несколько QR-кодов для каждого пользователя системы. А чтобы было интересно сканировать этот код, было решено добавить в него логотип.
Как это сделать читайте дальше.
Предисловие
QR-коды можно встретить везде, но как их отличить друг от друга? QR-коды всё время завоёвывают популярность, и нет-нет, да и встретятся несколько штук рядом. Зрелище это не из приятных — какой сканировать первым? И вообще, зачем сканировать то, от чего начинает рябить в глазах?
Решением такой задачи может служить персонализирование QR-кода: нестандартные цвета, логотип, или пояснительная надпись немного ниже самого кода, по которой можно понять — интересно ли зрителю это или нет.
Навеняка многие видели красивые QR-коды (а кто не видел, может посмотреть на хабре или на стороннем ресурсе), но мне стоит оговориться — чтобы создать такой, нужно вложить либо большие ресурсы в алгоритм генерации картинки, либо нарисовать такой код в фотошопе, но это будет единичный экземпляр, и для большинства из нас он не годится (если, конечно, есть вообще необходимость генерировать их самому).
Как это реализовано?
Создатели QR-кодов не расчитывали, что мы будем вставлять свои картинки в закодированные сообщения, коими являются сами коды, но они предусмотрели возможность высокого объёма восстановительной информации — код может содержать до 30% последней. Чем её больше — тем гуще картинка, но больше шансов, что пользователь раскодирует испорченный код. А портить мы его будем логотипом.
Для генерации кода использовалась библиотека ZXing — это open source библиотека для обработки различных 1D/2D штрихкодов, которая, кроме Java, имеет порты на другие языки.
Особенностью этой библиотеки является то, что она разбита на модули и распространяется в исходных кодах, которые необходимо компилировать. Но, к счастью, она есть в мавен репозитории — модуль core использовался для генерации, и модуль java se использовался для валидации кодов.
Для работы с графикой были использованы стандартные классы из пакета java.awt (JavaSE).
За дело!
Для экспериментов была сделана небольшаю консольная программа, которую можно найти на гитхабе — репозиторий опытного образца, которую я и разберу в этом разделе.
Тот, кому просто нужен QR-код, может написать следующее:
В противном случае так делать не стоит — по умолчанию библиотека добавит мало восстановительной информации, и даже если после вставки логотипа картинка расшифруется у нас на компьютере, то с фотокамеры она уже может считаться неправильно. По-этому будет хорошим тоном добавить максимум восстановительной информации, а раз мы будем изменять цвета и картинку, то не нужно спешить сохранять результат:
Создание картинки из матрицы кода делается в цикле — создаём картинку соответствующего размера и, проходя матрицу кода, отображаем наличие бита в матрице на картинку как информативный пиксель. Во время этого действа можно задать цвет фона и цвет кода:
Ну вот, теперь, когда мы оперируем картинкой, а не матрицей единиц и нулей, нам очень даже удобно и логотип в центр поместить, предварительно поправив его разрешение, чтобы не перекрывать весь код в случае слишком большого размера:
После нашего надругательства над кодом, обязательно стоит его проверить на правильность — хватит ли восстановительной информации для идеальной фотокамеры? И если хватит, то пора сохранить катинку и отдать её пользователю:
Поставленная цель достигнута — QR код сгенерирован. Спасибо за внимание!
Генерация штрих-кодов и QR-кодов на Java
В Java есть несколько библиотек, которые мы можем использовать для генерации штрих-кодов или QR-кодов. Здесь мы рассмотрим, как их использовать и интегрировать в веб-приложение.
1. Обзор
Штрих-коды используются для визуальной передачи информации. Скорее всего, мы предоставим соответствующее изображение штрих-кода на веб-странице, по электронной почте или в печатном документе.
В этом уроке мы рассмотрим, как генерировать наиболее распространенные типы штрих-кодов в Java.
Во-первых, мы узнаем о внутреннем устройстве нескольких типов штрих-кодов. Далее мы рассмотрим наиболее популярные библиотеки Java для генерации штрих-кодов. Наконец, мы увидим, как интегрировать штрих-коды в наше приложение, обслуживая их из веб-службы с помощью Spring Boot.
2. Типы штрих-кодов
Штрих-коды кодируют такую информацию, как номера продуктов, серийные номера и номера партий. Кроме того, они позволяют таким сторонам, как розничные торговцы, производители и транспортные поставщики, отслеживать активы по всей цепочке поставок.
Мы можем сгруппировать множество различных символов штрих-кодов в две основные категории:
2.1. Коды UPC (Универсальный код продукта)
UPC-коды являются одними из наиболее часто используемых 1D-штрих-кодов, и мы в основном находим их в Соединенных Штатах.
UPC-A-это только цифровой код, содержащий 12 цифр : идентификационный номер производителя (6 цифр), номер изделия (5 цифр) и контрольную цифру. Существует также код UPC-E, который имеет только 8 цифр и используется для небольших пакетов.
2.2. Коды EAN
Код EAN-13 является наиболее часто используемым стандартом EAN и аналогичен коду UPC. Он состоит из 13 цифр — ведущего “0”, за которым следует UPC-код.
2.3. Код 128
Штрих-код Code 128-это компактный линейный код высокой плотности, используемый в логистической и транспортной отраслях для заказа и распределения. Он может кодировать все 128 символов ASCII , и его длина является переменной.
2.4. PDF417
PDF417-это сложенный линейный штрих-код, состоящий из нескольких 1D штрих-кодов, уложенных один на другой. Следовательно, он может использовать традиционный линейный сканер.
Мы можем ожидать, что найдем его в различных приложениях, таких как проездные (посадочные талоны), идентификационные карты и управление запасами.
PDF417 использует исправление ошибок Рида-Соломона вместо контрольных цифр. Это исправление ошибок позволяет символу выдержать некоторое повреждение, не вызывая потери данных. Однако он может быть большим по размеру – в 4 раза больше, чем другие 2D-штрих-коды, такие как Datamatrix и QR-коды.
2.5. QR-коды
QR-коды становятся наиболее широко признанными 2D-штрих-кодами во всем мире. Большое преимущество QR-кода заключается в том, что мы можем хранить большие объемы данных в ограниченном пространстве.
Они используют четыре стандартизированных режима кодирования для эффективного хранения данных:
Кроме того, они гибки по размеру и легко сканируются с помощью смартфона. Подобно PDF417, QR-код может выдержать некоторые повреждения, не вызывая потери данных.
3. Библиотеки штрих-кодов
Мы собираемся исследовать несколько библиотек:
Barcode4j также является библиотекой с открытым исходным кодом. Кроме того, он предлагает форматы 2D – штрих – кодов, такие как DataMatrix и PDF417, и другие форматы вывода. Формат PDF417 доступен в обеих библиотеках. Но, в отличие от Barcode4j, Барбекю считает его линейным штрих-кодом.
ZXing (“пересечение зебры”)-это многоформатная библиотека обработки изображений штрих-кодов с открытым исходным кодом 1D/2D, реализованная на Java, с портами на другие языки. Это основная библиотека , которая поддерживает QR-коды на Java.
Библиотека QRGen предлагает простой API генерации QR-кода, построенный поверх ZXing. Он предоставляет отдельные модули для Java и Android.
4. Генерация Линейных Штрих-Кодов
Давайте создадим генератор изображений штрих-кодов для каждой библиотеки и пары штрих-кодов. Мы получим изображение в формате PNG, но мы также можем использовать другие форматы, такие как GIF или JPEG.
4.1. Использование библиотеки Барбекю
Как мы увидим, барбекю предоставляет простейший API для генерации штрих-кодов. Нам нужно только предоставить текст штрих-кода в качестве минимального ввода. Но мы могли бы дополнительно установить шрифт и разрешение (точки на дюйм). Что касается шрифта, мы можем использовать его для отображения текста штрих-кода под изображением.
Во-первых, нам нужно добавить зависимость Барбекю Maven:
Давайте создадим генератор для штрих-кода EAN13:
Мы можем генерировать изображения для остальных типов линейных штрих-кодов аналогичным образом.
Следует отметить, что нам не нужно указывать цифру контрольной суммы для штрих-кодов EAN/UPC, так как она автоматически добавляется библиотекой.
4.2. Использование библиотеки штрих-кодов
Давайте начнем с добавления зависимости Barcode Maven:
Аналогично, давайте построим генератор для штрих-кода EAN13:
4.3. Использование библиотеки ZXing
Здесь нам нужно добавить две зависимости Maven: библиотеку core image/| и клиент Java :
Давайте создадим генератор EAN13:
Здесь нам нужно указать несколько параметров в качестве входных данных, таких как текст штрих-кода, формат штрих-кода и размеры штрих-кода. В отличие от двух других библиотек, мы также должны добавить цифру контрольной суммы для штрих-кодов EAN. Но для штрих-кодов UPC-A контрольная сумма необязательна.
Кроме того, эта библиотека не будет отображать текст штрих – кода под изображением.
5. Генерация 2D Штрих-Кодов
5.1. Использование библиотеки ZXing
Мы собираемся использовать эту библиотеку для создания QR-кода. API аналогичен API линейных штрих-кодов:
5.2. Использование библиотеки QRGen
Во-первых, нам нужно добавить репозиторий jetpack и зависимость QRGen в ваш pom.xml:
Давайте создадим метод, который генерирует QR-код:
6. Создание службы ОТДЫХА
Теперь у нас есть выбор библиотеки штрих-кодов для использования, давайте рассмотрим, как обслуживать штрих-коды из веб-службы Spring Boot.
Мы начнем с RestController :
Наконец, мы можем использовать почтальона или браузер для просмотра сгенерированных штрих-кодов.
6.1. Генерация штрих-кода UPC-A
Давайте вызовем UPC-веб-сервис, использующий библиотеку барбекю:
6.2. Создание штрих-кода EAN13
Аналогично, мы собираемся вызвать веб-службу EAN13:
А вот наш штрих-код:
6.3. Генерация штрих-кода Code128
В этом случае мы будем использовать метод POST. Давайте вызовем веб-службу Code 128, используя библиотеку барбекю:
Мы предоставим тело запроса, содержащее данные:
Давайте посмотрим на результат:
6.4. Создание штрих-кода PDF417
Здесь мы собираемся вызвать веб-службу PDF417, которая похожа на код 128:
Мы предоставим тело запроса, содержащее данные:
И вот полученный штрих-код:
6.5. Создание штрих-кода QR-кода
Давайте вызовем веб-сервис QR-кода с помощью библиотеки ZXing:
Мы предоставим тело запроса, содержащее данные:
Здесь мы видим силу QR-кодов для хранения больших объемов данных в ограниченном пространстве.
7. Заключение
В этой статье мы узнали, как генерировать наиболее распространенные типы штрих-кодов в Java.
Во-первых, мы изучили форматы нескольких типов линейных и 2D штрих-кодов. Затем мы изучили самые популярные библиотеки Java для их создания. Хотя мы попробовали несколько простых примеров, мы можем изучить библиотеки дальше для более индивидуальных реализаций.
Наконец, мы увидели, как интегрировать генераторы штрих-кодов в службу REST и как их протестировать.
Генерируем и сканируем QR/BAR коды
В статье приводится короткий пример, как встроить в своё приложение генератор и/или сканер QR кодов (или штрих-кодов), и тем самым облегчить себе задачу передачи с устройства на устройство коротких объемов информации.
QR-коды пришли на смену устаревшим штрих-кодам (далее вместо ‘Bar code’) и все плотнее входят в нашу жизнь, их используют в десятках различных решений от передачи ссылок на сайт, до сложных систем авторизаций и покупок.
Подробно узнать что такое QR-код можно в подробностях узнать из статьи Читаем QR код
Сканируем QR-коды
Тут есть одна особенность, result = scanner.scanImage(codeImage) иногда возвращет корректный результат, даже когда нет никакого QR-кода перед камерой. То есть, камера иногда распознает что то даже в обычной размытой картинке. Поэтому рекомендую ввести дополнительную проверку на размер прочитанного кода или на соответствие ожидаемому формату.
Генерируем QR-коды
В этом случае уже будут задействованы ресурсы библиотеки ZXing.
Входные парамеры encodeAsBitmap: текст или код для кодирования, стандарт в который мы кодируем, размеры картинки на выходе.
Что на счёт Штрих-кодов?
Сканер понимает все виды штрих-кодов без каких-либо модификаций, из коробки.
Генератор же модифицируется не просто, а очень просто:
в функцию encodeAsBitmap передаем в поле format вместо BarcodeFormat.QR_CODE, что нибудь вроде BarcodeFormat.CODE_128, что будет соответствовать штрих-коду стандарта Code 128
Пару советов напоследок
Имейте ввиду, что работа с камерой может иметь свои особенности на разных платформах
Замечено, что метод
постоянно теряет память (есть Memory Leak) ввиду того что буфер кадра постоянно создается и очищается на каждом новом превью кадре с камеры.
Для того, что бы этого избежать, есть возможность использовать CallbackBuffer для выделения статичного буфера под превью кадры.
Это действительно помогает избавится от утечек памяти и даже увеличивает фрейм-рейт у превью картинки с камеры.
Но!, нашлась модель телефона, которая ни в какую не захотела работать с превью буфером и не факт что не найдутся еще, поэтому оставил в примере более надежный способ.
Генерация штрихкодов имеет ограничения согласно выбранному стандарту: максимальный размер в байтах, разрешенные смиволы и т.д.
Изучите особенности линейных штрикодов, для того что бы обеспечить совместимость отображаемых вами штрих-кодов с магазинными сканерами
Обзор JavaScript-сканнеров штрихкодов
Недавно появилась идея сэкономить на ТСД на складе и попробовать использовать вместо них обычные дешёвые мобильники (даже без пылезащиты). Интерфейс планирую реализовать в виде веб-приложения (обычные веб-странички, HTML + CSS + JS).
Для того, чтобы всё получилось, необходимо научить веб-странички сканировать штрихкода через камеру телефона. Получить данные с камеры достаточно просто. Основная работа состоит в обработке кадра. Под катом обзор существующих готовых решений и много картинок.
quaggaJS
На сайте проекта присутствует страничка, где можно загрузить образцы и попробовать библиотеку в деле. Пробуем образец №1. Необходимо указать некоторые настройки, ок, не вопрос.
В результате запуска определить штрихкод не удалось, но расположение штрихкода определено неплохо.
Пробуем образец №2. Как-то безрадостно.
Возможно он лучше работает с картинками высокого разрешения. Хорошо, делаем третий образец (образец №3).
Честно говоря я не знаю какой это тип штрихкода и попробовал все настройки — ШК не определился. Хорошо, давайте попробуем ещё один образец высокого разрешения (образец №4):
Почему-то ни с какими настройками результата добиться не удалось.
Попробуем «чистый» образец от следующей библиотеки (образец №5):
javascript-barcode-reader
Или можно скачать всего один файлик: javascript-barcode-reader.min.js размером 10 445 байт.
У проекта есть страничка с примерами, однако картинки получены путём генерации кодов, а не с камеры. Нам такое не пойдёт.
Образец №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
Пробуем первый образец:
Результат: 000204892734. Образец распознан.
Берём образец №2 (EAN-13). Только чтоб заработало, необходимо строку 32 скрипта написать так:
Результат: XXXXXXXXXXXX. Образец не распознан.
Результат: XXXXXXXXXXXX. Не распознан.
Давайте попробуем что-то простое:
Результат: не распознан. Возможно ему нужно подавать так, чтобы кроме штрихкода на картинке ничего не было, исключая и лишнее пространство.
EddieLa BarcodeReader
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
Образец №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 не подходит).
Если вам известна библиотека, отвечающая данным требованиям, и отсутствующая в статье — просьба сообщить.
Полученный рейтинг библиотек таков:
Статья состоялась благодаря интернет-магазину освещения Дивайн Лайт.