Generating Barcodes and QR Codes in Java – 在Java中生成条形码和QR码

最后修改: 2020年 1月 25日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Barcodes are used to convey information visually. We’ll most likely provide an appropriate barcode image in a web page, email, or a printable document.

条码是用来直观地传达信息的。我们很可能在网页、电子邮件或可打印的文件中提供一个适当的条形码图像。

In this tutorial, we’re going to look at how to generate the most common types of barcodes in Java.

在本教程中,我们要看一下如何在Java中生成最常见的条形码类型。

First, we’ll learn about the internals of several types of barcodes. Next, we’ll explore the most popular Java libraries for generating barcodes. Finally, we’ll see how to integrate barcodes into our application by serving them from a web service using Spring Boot.

首先,我们将了解几种类型的条形码的内部结构。接下来,我们将探索用于生成条形码的最流行的Java库。最后,我们将了解如何通过使用Spring Boot从web service中提供条形码来将其集成到我们的应用程序中。

2. Types of Barcodes

2.条码的类型

Barcodes encode information such as product numbers, serial numbers, and batch numbers. Also, they enable parties like retailers, manufacturers, and transport providers to track assets through the entire supply chain.

条码对产品编号、序列号和批号等信息进行编码。而且,它们使零售商、制造商和运输商等各方能够通过整个供应链追踪资产。

We can group the many different barcode symbologies into two primary categories:

我们可以将许多不同的条形码符号学分为两个主要类别。

  • linear barcodes
  • 2D barcodes

2.1. UPC (Universal Product Code) Codes

2.1.UPC(通用产品代码)代码

UPC Codes are some of the most commonly used 1D barcodes, and we mostly find them in the United States.

UPC码是一些最常用的一维条形码,我们大多在美国发现它们。

The UPC-A is a numeric-only code that contains 12 digits: a manufacturer identification number (6 digits), an item number (5 digits), and a check digit. There is also a UPC-E code that has only 8 digits and is used for small packages.

UPC-A是一个只包含数字的代码,包含12位数字:制造商识别码(6位),商品编号(5位),和一个校验码。还有一种UPC-E编码,只有8位数字,用于小包装。

2.2. EAN Codes

2.2 EAN代码

EAN Codes are known worldwide as both European Article Number and International Article Number. They’re designed for Point-of-Sale scanning. There are also a few different variations of the EAN code, including EAN-13, EAN-8, JAN-13, and ISBN.

EAN码在世界范围内被称为欧洲商品编号和国际商品编号。它们被设计用于销售点扫描。EAN码也有一些不同的变化,包括EAN-13、EAN-8、JAN-13和ISBN。

The EAN-13 code is the most commonly used EAN standard and is similar to the UPC code. It’s made of 13 digits — a leading “0” followed by the UPC-A code.

EAN-13代码是最常用的EAN标准,与UPC代码相似。它由13位数字组成–前面是 “0”,后面是UPC-A代码。

2.3. Code 128

2.3 Code 128

The Code 128 barcode is a compact, high-density linear code used in the logistics and transportation industries for ordering and distribution. It can encode all 128 characters of ASCII, and its length is variable.

Code 128条码是一种紧凑、高密度的线性代码,用于物流和运输行业的订购和分配。它可以编码ASCII的所有128个字符,其长度是可变的。

2.4. PDF417

2.4. PDF417

PDF417 is a stacked linear barcode comprised of multiple 1D barcodes stacked one on top of another. Hence, it can use a traditional linear scanner.

PDF417是一个由多个一维条码叠加而成的堆叠式线性条码。因此,它可以使用传统的线性扫描仪。

We might expect to find it on a variety of applications such as travel (boarding passes), identification cards, and inventory management.

我们可能期望在各种应用中发现它,如旅行(登机牌)、识别卡和库存管理。

PDF417 uses Reed-Solomon error correction instead of check digits. This error correction allows the symbol to endure some damage without causing loss of data. However, it can be expansive in size – 4 times larger than other 2D barcodes such as Datamatrix and QR Codes.

PDF417使用Reed-Solomon纠错,而不是检查数字。这种纠错方式使符号能够承受一些损坏而不会造成数据丢失。然而,它的尺寸可能很大–比其他二维条码,如Datamatrix和QR码大4倍。

2.5. QR Codes

2.5.二维码

QR Codes are becoming the most widely recognized 2D barcodes worldwide. The big benefit of the QR code is that we can store large amounts of data in a limited space.

二维码正在成为全世界最广泛认可的二维条码。二维码的最大好处是我们可以在有限的空间内存储大量的数据。

They use four standardized encoding modes to store data efficiently:

它们使用四种标准化的编码模式来有效存储数据。

  • numeric
  • alphanumeric
  • byte/binary
  • kanji

Moreover, they are flexible in size and are easily scanned using a smartphone. Similar to PDF417, a QR code can withstand some damage without causing loss of data.

此外,它们的尺寸很灵活,很容易用智能手机扫描。与PDF417类似,二维码可以承受一些损坏而不会造成数据丢失。

3. Barcode Libraries

3.条形码库

We’re going to explore several libraries:

我们将探索几个图书馆。

  • Barbecue
  • Barcode4j
  • ZXing
  • QRGen

Barbecue is an open-source Java library that supports an extensive set of 1D barcode formats. Also, the barcodes can be output to PNG, GIF, JPEG, and SVG.

Barbecue是一个开源的Java库,它支持一组广泛的一维条码格式。同时,条形码可以输出为PNG、GIF、JPEG和SVG。

Barcode4j is also an open-source library. In addition, it offers 2D barcode formats – like DataMatrix and PDF417 – and more output formats. The PDF417 format is available in both libraries. But, unlike Barcode4j, Barbecue considers it a linear barcode.

Barcode4j也是一个开源的库。此外,它还提供二维条码格式–如DataMatrix和PDF417–以及更多的输出格式。PDF417格式在这两个库中都是可用的。但是,与Barcode4j不同,Barbecue认为它是一种线性条码。

ZXing (“zebra crossing”) is an open-source, multi-format 1D/2D barcode image processing library implemented in Java, with ports to other languages. This is the main library that supports QR codes in Java.

ZXing(”斑马线”)是一个开源的、多格式的一维/二维条码图像处理库,用Java实现,并可移植到其他语言。这是在Java中支持QR码的主要库。

QRGen library offers a simple QRCode generation API built on top of ZXing. It provides separate modules for Java and Android.

QRGen库提供了一个建立在ZXing之上的简单QRCode生成API。它为Java和Android提供了单独的模块。

4. Generating Linear Barcodes

4.生成线性条码

Let’s create a barcode image generator for each library and barcode pair. We’ll retrieve the image in the PNG format, but we could also use other formats like GIF or JPEG.

让我们为每个库和条码对创建一个条码图像生成器。我们将检索PNG格式的图像,但我们也可以使用其他格式,如GIF或JPEG。

4.1. Using the Barbecue Library

4.1.使用Barbecue库

As we’ll see, Barbecue provides the simplest API for generating barcodes. We only need to provide the barcode text as minimal input. But we could optionally set a font and a resolution (dots per inch). Regarding the font, we can use it to display the barcode text under the image.

正如我们将看到的,Barbecue为生成条形码提供了最简单的API。我们只需要提供条形码文本作为最小的输入。但是我们可以选择设置一个字体和一个分辨率(每英寸点数)。关于字体,我们可以用它来显示图像下的条形码文本。

First, we need to add the Barbecue Maven dependency:

首先,我们需要添加BarbecueMaven依赖项。

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

Let’s create a generator for an EAN13 barcode:

让我们创建一个EAN13条码的生成器。

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

    return BarcodeImageHandler.getImage(barcode);
}

We can generate images for the rest of the linear barcode types in a similar manner.

我们可以以类似的方式为其余的线性条码类型生成图像。

We should note that we do not need to provide the checksum digit for EAN/UPC barcodes, as it is automatically added by the library.

我们应该注意,我们不需要为EAN/UPC条形码提供校验码,因为它是由库自动添加的。

4.2. Using the Barcode4j Library

4.2.使用Barcode4j库

Let’s start by adding the Barcode4j Maven Dependency:

我们首先添加Barcode4jMaven依赖项。

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

Likewise, let’s build a generator for an EAN13 barcode:

同样地,让我们建立一个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();
}

The BitmapCanvasProvider constructor takes several parameters: resolution, image type, whether to enable anti-aliasing, and image orientation. Also, we don’t need to set a font because the text under the image is displayed by default.

BitmapCanvasProvider构造函数需要几个参数:分辨率、图像类型、是否启用抗锯齿,以及图像方向。另外,我们不需要设置字体,因为图像下的文本是默认显示的

4.3. Using the ZXing Library

4.3.使用ZXing库

Here, we need to add two Maven dependencies: the core image library and the Java client:

在这里,我们需要添加两个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>

Let’s create an EAN13 generator:

让我们创建一个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);
}

Here, we need to provide several parameters as input, such as a barcode text, a barcode format, and barcode dimensions. Unlike the other two libraries, we must also add the checksum digit for EAN barcodes. But, for UPC-A barcodes, the checksum is optional.

在这里,我们需要提供几个参数作为输入,如条形码文本、条形码格式和条形码尺寸。与其他两个库不同,我们还必须为EAN条形码添加校验码。但是,对于UPC-A条形码,校验和是可选的。

Moreover, this library will not display barcode text under the image.

此外,这个库不会在图像下显示条形码文本。

5. Generating 2D Barcodes

5.生成二维条码

5.1. Using the ZXing Library

5.1.使用ZXing库

We’re going to use this library to generate a QR Code. The API is similar to that of the linear barcodes:

我们将使用这个库来生成一个QR码。其API与线性条码的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. Using the QRGen Library

5.2.使用QRGen库

The library is no longer deployed to Maven Central, but we can find it on jitpack.io.

该库已不再部署到Maven中心,但我们可以在jitpack.io上找到它。

First, we need to add the jitpack repository and the QRGen dependency to our pom.xml:

首先,我们需要在pom.xml中添加jitpack资源库和QRGen依赖。

<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>

Let’s create a method that generates a QR Code:

让我们创建一个方法,生成一个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);
}

As we can see, the API is based on the Builder pattern and it provides two types of output: File and OutputStream. We can use the ImageIO library to convert it to a BufferedImage.

正如我们所看到的,该API基于Builder模式,它提供两种类型的输出。文件OutputStream。我们可以使用ImageIO库来将其转换为BufferedImage

6. Building a REST Service

6.构建一个REST服务

Now we have a choice of barcode library to use, let’s look at how to serve barcodes from a Spring Boot web service.

现在我们可以选择使用条形码库了,让我们看看如何从Spring Boot网络服务中提供条形码。

We’ll start with a RestController:

我们将从一个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));
    }
    //...
}

Also, we need to manually register a message converter for BufferedImage HTTP Responses because there is no default:

另外,我们需要手动为BufferedImage HTTP响应注册一个消息转换器,因为没有默认。

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

Finally, we can use Postman or a browser to view the generated barcodes.

最后,我们可以使用Postman或浏览器来查看生成的条形码。

6.1. Generating a UPC-A Barcode

6.1.生成一个UPC-A条码

Let’s call the UPC-A web service using the Barbecue library:

让我们使用Barbecue库调用UPC-A网络服务。

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

Here’s the result:

结果是这样的。

6.2. Generating an EAN13 Barcode

6.2.生成一个EAN13条码

Similarly, we’re going to call the EAN13 web service:

同样地,我们要调用EAN13网络服务。

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

And here’s our barcode:

这是我们的条形码。

6.3. Generating a Code128 Barcode

6.3.生成一个Code128条码

In this case, we’re going to use the POST method. Let’s call the Code128 web service using the Barbecue library:

在这种情况下,我们将使用POST方法。让我们使用Barbecue库调用Code128网络服务。

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

We’ll provide the request body, containing the data:

我们将提供请求主体,包含数据。

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

Let’s see the result:

让我们看看结果。

6.4. Generating a PDF417 Barcode

6.4.生成一个PDF417条码

Here, we’re going to call the PDF417 web service, which is similar to Code128:

在这里,我们要调用PDF417网络服务,它与Code128类似。

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

We’ll provide the request body, containing the data:

我们将提供请求主体,包含数据。

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

And here’s the resulting barcode:

这里是产生的条形码。

6.5. Generating a QR Code Barcode

6.5.生成一个QR码条码

Let’s call the QR Code web service using the ZXing library:

让我们使用ZXing库调用QR码网络服务。

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

We’ll provide the request body, containing the data:

我们将提供请求主体,包含数据。

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.

Here’s our QR code:

这是我们的QR码。

Here, we can see the power of QR codes to store large amounts of data in a limited space.

在这里,我们可以看到二维码在有限空间内存储大量数据的力量。

7. Conclusion

7.结语

In this article, we learned how to generate the most common types of barcodes in Java.

在这篇文章中,我们学习了如何在Java中生成最常见的条形码类型。

First, we studied the formats of several types of linear and 2D barcodes. Next, we explored the most popular Java libraries for generating them. Though we tried some simple examples, we can study the libraries further for more customized implementations.

首先,我们研究了几种类型的线性和二维条码的格式。接下来,我们探索了最流行的用于生成条形码的Java库。虽然我们尝试了一些简单的例子,但我们可以进一步研究这些库,以获得更多的定制实现。

Finally, we saw how to integrate the barcode generators into a REST service, and how to test them.

最后,我们看到了如何将条形码生成器集成到一个REST服务中,以及如何测试它们。

As always, the example code from this tutorial is available over on GitHub.

一如既往,本教程中的示例代码可在GitHub上获取。