Перейти к основному содержимому

Генерация штрих-кодов и QR-кодов в Java

· 8 мин. чтения

1. Обзор

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

В этом уроке мы рассмотрим, как генерировать наиболее распространенные типы штрих-кодов в Java.

Во-первых, мы узнаем о внутренностях нескольких типов штрих-кодов. Далее мы рассмотрим самые популярные библиотеки Java для создания штрих-кодов. Наконец, мы увидим, как интегрировать штрих-коды в наше приложение, предоставляя их из веб-службы с помощью Spring Boot.

2. Типы штрих-кодов

Штрих-коды кодируют такую информацию, как номера продуктов, серийные номера и номера партий. Кроме того, они позволяют таким сторонам, как розничные торговцы, производители и поставщики транспортных услуг, отслеживать активы по всей цепочке поставок.

Мы можем сгруппировать множество различных символик штрих-кода в две основные категории:

  • линейные штрих-коды
  • 2D штрих-коды

2.1. Коды UPC (универсальный код продукта)

Коды UPC являются одними из наиболее часто используемых одномерных штрих-кодов, и мы в основном находим их в Соединенных Штатах.

UPC-A — это цифровой код, состоящий из 12 цифр : идентификационный номер производителя (6 цифр), номер изделия (5 цифр) и контрольная цифра. Существует также код UPC-E, который состоит всего из 8 цифр и используется для небольших посылок.

2.2. Коды EAN

Коды EAN известны во всем мире как европейский артикульный номер и международный артикульный номер . Они предназначены для сканирования точек продаж. Существует также несколько различных вариантов кода EAN, включая EAN-13, EAN-8, JAN-13 и ISBN.

Код EAN-13 является наиболее часто используемым стандартом EAN и подобен коду UPC. Он состоит из 13 цифр — ведущего «0», за которым следует код UPC-A.

2.3. Код 128

Штрих-код Code 128 представляет собой компактный линейный код высокой плотности, используемый в логистике и транспортной отрасли для размещения заказов и распределения. Он может кодировать все 128 символов ASCII , а его длина может быть переменной.

2.4. PDF417

PDF417 — это сложенный линейный штрих-код, состоящий из нескольких одномерных штрих-кодов, наложенных друг на друга. Следовательно, он может использовать традиционный линейный сканер.

Мы могли бы ожидать найти его в различных приложениях, таких как путешествия (посадочные талоны), удостоверения личности и управление запасами.

PDF417 использует исправление ошибок Рида-Соломона вместо контрольных цифр. Это исправление ошибок позволяет символу выдерживать некоторые повреждения, не вызывая потери данных. Тем не менее, он может быть обширным по размеру — в 4 раза больше, чем другие 2D-штрих-коды, такие как Datamatrix и QR-коды.

2.5. QR-коды

QR-коды становятся наиболее широко признанными 2D-штрих-кодами во всем мире. Большим преимуществом QR-кода является то, что мы можем хранить большие объемы данных в ограниченном пространстве.

Они используют четыре стандартизированных режима кодирования для эффективного хранения данных:

  • числовой
  • буквенно-цифровой
  • байт/двоичный
  • кандзи

Кроме того, они имеют гибкий размер и легко сканируются с помощью смартфона. Подобно PDF417, QR-код может выдержать некоторые повреждения, не вызывая потери данных.

3. Библиотеки штрих-кодов

Мы собираемся изучить несколько библиотек:

  • Барбекю
  • Штрих-код4j
  • ZXing
  • QRGen

Barbecue — это библиотека Java с открытым исходным кодом, которая поддерживает обширный набор форматов одномерных штрих-кодов. Кроме того, штрих-коды можно выводить в формате PNG, GIF, JPEG и SVG.

Barcode4j также является библиотекой с открытым исходным кодом. Кроме того, он предлагает форматы 2D-штрих-кодов, такие как DataMatrix и PDF417, и другие выходные форматы. Формат PDF417 доступен в обеих библиотеках. Но, в отличие от Barcode4j, Barbecue считает его линейным штрих-кодом.

ZXing («зебра») — это многоформатная библиотека обработки изображений 1D/2D штрих-кодов с открытым исходным кодом, реализованная на Java с портами на другие языки. Это основная библиотека, поддерживающая QR-коды в Java.

Библиотека QRGen предлагает простой API генерации QRCode, построенный поверх ZXing. Он предоставляет отдельные модули для Java и Android.

4. Создание линейных штрих-кодов

Давайте создадим генератор изображения штрих-кода для каждой пары библиотеки и штрих-кода. Мы получим изображение в формате PNG, но мы также можем использовать другие форматы, такие как GIF или JPEG.

4.1. Использование библиотеки барбекю

Как мы увидим, Barbecue предоставляет простейший API для создания штрих-кодов. Нам нужно только предоставить текст штрих-кода в качестве минимального ввода. Но мы могли бы дополнительно установить шрифт и разрешение (точек на дюйм). Что касается шрифта, мы можем использовать его для отображения текста штрих-кода под изображением.

Во-первых, нам нужно добавить зависимость Barbecue Maven:

<dependency>
<groupId>net.sourceforge.barbecue</groupId>
<artifactId>barbecue</artifactId>
<version>1.5-beta1</version>
</dependency>

Давайте создадим генератор штрих-кода EAN13:

public static BufferedImage generateEAN13BarcodeImage(String barcodeText) throws Exception {
Barcode barcode = BarcodeFactory.createEAN13(barcodeText);
barcode.setFont(BARCODE_TEXT_FONT);

return BarcodeImageHandler.getImage(barcode);
}

Мы можем генерировать изображения для остальных типов линейных штрих-кодов аналогичным образом.

Следует отметить, что нам не нужно указывать цифру контрольной суммы для штрих-кодов EAN/UPC, так как она автоматически добавляется библиотекой.

4.2. Использование библиотеки Barcode4j

Начнем с добавления зависимости Barcode4j Maven:

<dependency>
<groupId>net.sf.barcode4j</groupId>
<artifactId>barcode4j</artifactId>
<version>2.1</version>
</dependency>

Аналогичным образом создадим генератор штрих-кода EAN13:

public static BufferedImage generateEAN13BarcodeImage(String barcodeText) {
EAN13Bean barcodeGenerator = new EAN13Bean();
BitmapCanvasProvider canvas =
new BitmapCanvasProvider(160, BufferedImage.TYPE_BYTE_BINARY, false, 0);

barcodeGenerator.generateBarcode(canvas, barcodeText);
return canvas.getBufferedImage();
}

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

4.3. Использование библиотеки ZXing

Здесь нам нужно добавить две зависимости Maven: основную библиотеку изображений и клиент Java :

<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>

Давайте создадим генератор EAN13:

public static BufferedImage generateEAN13BarcodeImage(String barcodeText) throws Exception {
EAN13Writer barcodeWriter = new EAN13Writer();
BitMatrix bitMatrix = barcodeWriter.encode(barcodeText, BarcodeFormat.EAN_13, 300, 150);

return MatrixToImageWriter.toBufferedImage(bitMatrix);
}

Здесь нам нужно указать несколько параметров в качестве входных данных, таких как текст штрих-кода, формат штрих-кода и размеры штрих-кода. В отличие от двух других библиотек, мы также должны добавить цифру контрольной суммы для штрих-кодов EAN. Но для штрих-кодов UPC-A контрольная сумма необязательна.

Более того, эта библиотека не будет отображать текст штрих-кода под изображением.

5. Генерация 2D штрих-кодов

5.1. Использование библиотеки ZXing

Мы собираемся использовать эту библиотеку для создания QR-кода. API аналогичен линейным штрих-кодам:

public static BufferedImage generateQRCodeImage(String barcodeText) throws Exception {
QRCodeWriter barcodeWriter = new QRCodeWriter();
BitMatrix bitMatrix =
barcodeWriter.encode(barcodeText, BarcodeFormat.QR_CODE, 200, 200);

return MatrixToImageWriter.toBufferedImage(bitMatrix);
}

5.2. Использование библиотеки QRGen

Библиотека больше не развернута в Maven Central, но мы можем найти ее на jitpack.io .

Во-первых, нам нужно добавить репозиторий jitpack и зависимость QRGen в наш pom.xml:

<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>com.github.kenglxn.qrgen</groupId>
<artifactId>javase</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>

Давайте создадим метод, который генерирует QR-код:

public static BufferedImage generateQRCodeImage(String barcodeText) throws Exception {
ByteArrayOutputStream stream = QRCode
.from(barcodeText)
.withSize(250, 250)
.stream();
ByteArrayInputStream bis = new ByteArrayInputStream(stream.toByteArray());

return ImageIO.read(bis);
}

Как мы видим, API основан на шаблоне Builder и обеспечивает два типа вывода: File и OutputStream . Мы можем использовать библиотеку ImageIO , чтобы преобразовать его в BufferedImage .

6. Создание службы REST

Теперь у нас есть выбор используемой библиотеки штрих-кодов, давайте посмотрим, как обслуживать штрих-коды из веб-службы Spring Boot.

Мы начнем с RestController :

@RestController
@RequestMapping("/barcodes")
public class BarcodesController {

@GetMapping(value = "/barbecue/ean13/{barcode}", produces = MediaType.IMAGE_PNG_VALUE)
public ResponseEntity<BufferedImage> barbecueEAN13Barcode(@PathVariable("barcode") String barcode)
throws Exception {
return okResponse(BarbecueBarcodeGenerator.generateEAN13BarcodeImage(barcode));
}
//...
}

Кроме того, нам нужно вручную зарегистрировать конвертер сообщений для HTTP-ответов BufferedImage , потому что по умолчанию нет:

@Bean
public HttpMessageConverter<BufferedImage> createImageHttpMessageConverter() {
return new BufferedImageHttpMessageConverter();
}

Наконец, мы можем использовать Postman или браузер для просмотра сгенерированных штрих-кодов.

6.1. Создание штрих-кода UPC-A

Вызовем веб-сервис UPC-A с помощью библиотеки Barbecue:

[GET] http://localhost:8080/barcodes/barbecue/upca/12345678901

Вот результат:

./5aeb99299f82b559f39bd98e66a553e0.png

6.2. Генерация штрих-кода EAN13

Точно так же мы собираемся вызвать веб-службу EAN13:

[GET] http://localhost:8080/barcodes/barbecue/ean13/012345678901

А вот и наш штрих-код:

./566bfd81c0f563c69da0f0ece9bf0524.png

6.3. Создание штрих-кода Code128

В этом случае мы собираемся использовать метод POST. Вызовем веб-сервис Code128 с помощью библиотеки Barbecue:

[POST] http://localhost:8080/barcodes/barbecue/code128

Мы предоставим тело запроса, содержащее данные:

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Посмотрим на результат:

./b1b3d70b30f95fdd6a1568e5e8c67b70.png

6.4. Создание штрих-кода PDF417

Здесь мы собираемся вызвать веб-службу PDF417, аналогичную Code128:

[POST] http://localhost:8080/barcodes/barbecue/pdf417

Мы предоставим тело запроса, содержащее данные:

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

И вот получившийся штрих-код:

./419a1214a39711492a809c11d1b1df79.png

6.5. Создание штрих-кода QR-кода

Вызовем веб-сервис QR Code с помощью библиотеки ZXing:

[POST] http://localhost:8080/barcodes/zxing/qrcode

Мы предоставим тело запроса, содержащее данные:

Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Вот наш QR-код:

./68ebd0af22c5b0b6c516ecdee6f94db2.png

Здесь мы видим возможности QR-кодов для хранения больших объемов данных в ограниченном пространстве.

7. Заключение

В этой статье мы узнали, как генерировать наиболее распространенные типы штрих-кодов в Java.

Сначала мы изучили форматы нескольких типов линейных и двумерных штрих-кодов. Далее мы изучили самые популярные библиотеки Java для их создания. Хотя мы попробовали несколько простых примеров, мы можем продолжить изучение библиотек для более индивидуальных реализаций.

Наконец, мы увидели, как интегрировать генераторы штрих-кодов в службу REST и как их тестировать.

Как всегда, пример кода из этого руководства доступен на GitHub .