1. Overview
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.
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.
2. Types of Barcodes
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
UPC Codes are some of the most commonly used 1D barcodes, and we mostly find them in the United States.
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.
2.2. EAN Codes
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.
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.
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.
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.
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.
2.5. QR Codes
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.
3. Barcode Libraries
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.
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.
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.
QRGen library offers a simple QRCode generation API built on top of ZXing. It provides separate modules for Java and Android.
4. Generating Linear Barcodes
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.
4.1. Using the Barbecue Library
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.
First, we need to add the Barbecue Maven dependency:
<dependency> <groupId>net.sourceforge.barbecue</groupId> <artifactId>barbecue</artifactId> <version>1.5-beta1</version> </dependency>
Let's create a generator for an EAN13 barcode:
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.
4.2. Using the Barcode4j Library
Let's start by adding the Barcode4j Maven Dependency:
<dependency> <groupId>net.sf.barcode4j</groupId> <artifactId>barcode4j</artifactId> <version>2.1</version> </dependency>
Likewise, let's build a generator for an EAN13 barcode:
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.
4.3. Using the ZXing Library
Here, we need to add two Maven dependencies: the core image library and the Java client:
<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:
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.
Moreover, this library will not display barcode text under the image.
5. Generating 2D Barcodes
5.1. Using the ZXing Library
We're going to use this library to generate a QR Code. The API is similar to that of the linear barcodes:
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
The library is no longer deployed to Maven Central, but we can find it on jitpack.io.
First, we need to add the jitpack repository and the QRGen dependency to our 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>
Let's create a method that generates a QR Code:
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.
6. Building a REST Service
Let's look at how to serve barcodes from a web service. We'll start with a 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:
@Bean public HttpMessageConverter<BufferedImage> createImageHttpMessageConverter() { return new BufferedImageHttpMessageConverter(); }
Finally, we can use Postman or a browser to view the generated barcodes.
6.1. Generating a UPC-A Barcode
Let's call the UPC-A web service using the Barbecue library:
[GET] http://localhost:8080/barcodes/barbecue/upca/12345678901
Here's the result:
6.2. Generating an EAN13 Barcode
Similarly, we're going to call the EAN13 web service:
[GET] http://localhost:8080/barcodes/barbecue/ean13/012345678901
And here's our barcode:
6.3. Generating a Code128 Barcode
In this case, we're going to use the POST method. Let's call the Code128 web service using the Barbecue library:
[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
Here, we're going to call the PDF417 web service, which is similar to 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
Let's call the QR Code web service using the ZXing library:
[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:
Here, we can see the power of QR codes to store large amounts of data in a limited space.
7. Conclusion
In this article, we learned how to generate the most common types of barcodes in 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.
Finally, we saw how to integrate the barcode generators into a REST service, and how to test them.
As always, the example code from this tutorial is available over on GitHub.