Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Building Java Barcode Apps: Command Line, GUI, and Web

19 Mar 2020 1  
This article aims to help Java developers to integrate Java barcode SDKs into different Java applications.
In this article we go over the Differences between ZXing and Dynamsoft Barcode Reader. Like the the supported symbologies, and memory usage. Then we go over how you can use Java to create different types of applications, including a GUI app, Web App, and Android.

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

For the past 20 years, although there have been many new programming languages that sprang out, Java had always ranked in the top 3 programming languages. Why is Java still popular despite it being so old? Java is not only widely used in enterprise and cloud applications, but it is also the primary programming language for developing Android apps. This article aims to help Java developers to integrate Java barcode SDKs into different Java applications.

Overview

In the 21st century, barcodes are ubiquitous. The usage of Barcode technology is demanded in a variety of industries, such as healthcare, insurance, retail, logistics, banking, education, and so on. There are tons of barcode symbologies, and barcode images needed to be processed every second of every day. The requirements are enormous, and therefore lots of enterprises get started to bring the barcode decoding functionality to their system. One of the most argued questions is whether we should use a free or a commercial barcode library. In the following paragraphs, you will see how to use ZXing (free) or Dynamsoft Barcode Reader(commercial) in Java barcode applications. If you are interested in other Java barcode SDKs, it is easy to substitute the decoding part based on the source code to test other SDKs.

The Differences between ZXing and Dynamsoft Barcode Reader

Let’s put aside the topic of free and commercial SDK, and focus on the comparison between ZXing and Dynamsoft Barcode Reader in terms of SDK implementation, symbologies, decoding methods, and memory usage.

SDK Implementation

The open-source project ZXing is a barcode scanning library written in Java.

Dynamsoft Barcode Reader is an enterprise-class barcode SDK written in C/C++. The Java APIs of Dynamsoft Barcode Reader are encapsulated based on JNI (Java Native Interface).

Symbologies

The supported symbologies of ZXing include UPC-A, UPC-E, EAN-8, EAN-13, UPC/EAN Extension 2/5, Code 39, Code 93, Code 128, Codabar, ITF, QR Code, Data Matrix, Aztec, PDF 417, MaxiCode, RSS-14, and RSS-Expanded.

The supported symbologies of Dynamsoft Barcode Reader include UPC-A, UPC-E, EAN-8, EAN-13, Industrial 2 of 5, Interleaved 2 of 5, Code 11, Codabar, Code 39, Code 93, Code 128, QR Code, PDF417, DataMatrix, MaxiCode, Aztec Code, DataBar, GS1 Composite Code, USPS Intelligent Mail, Postnet, Planet, Australian Post and UK Royal Mail.

Decoding Methods

ZXing only provides methods of decoding barcodes from an image buffer, for it does not contain any image codecs.

Dynamsoft Barcode SDK contains image codecs, which brings better user experience. It supports decoding barcodes from image files (BMP, JPEG, PNG, Gif, TIFF and PDF), file stream, and image buffer.

Memory Usage

ZXing is written in Java, and thus the memory of the image buffer for ZXing is allocated on the JVM heap. By default, JVM heap size is limited, which means it is easy to drain out heap memory and cause app crashes accidentally if the size of the processed image is too big and the garbage collection is not triggered in time.

In contrast to ZXing, you do not need to worry about memory usage when using Dynamsoft Barcode Reader, which allocates memory and does image processing in C/C++.

Java Barcode Reader Apps for Desktops

On the desktop operating systems, we can use Java to create different types of applications. Here we have an image for testing the SDK performance.

Image 1

Configure the Maven dependencies for ZXing and Dynamsoft Barcode Reader:

<repositories>
        <repository>
            <id>dbr</id>
            <url>https://download.dynamsoft.com/maven/dbr/jar</url>
        </repository>
    </repositories>
<dependencies>
        <dependency>
            <groupId>com.dynamsoft</groupId>
            <artifactId>dbr</artifactId>
            <version>7.3</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.4.0</version>
          </dependency>
</dependencies>

To activate Dynamsoft Barcode Reader, apply for a free trial license from the online portal.

Command Line Application

  1. Create a new Maven project:
mvn archetype:generate -DgroupId=com.java.barcode -DartifactId=app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
  1. Import ZXing and Dynamsoft Barcode Reader:
import com.dynamsoft.barcode.*;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.multi.*;
  1. Decode the image file with ImageIO and BufferedImage:
import java.awt.image.*;
import javax.imageio.ImageIO;
BufferedImage image = null;
        try {
            image = ImageIO.read(new File(filename));
        } catch (IOException e) {
            System.out.println(e);
            return;
        }
  1. Enable multi-barcode support

The testing image contains multiple barcodes. To read multiple barcodes encoded with different barcode symbologies, we need to use MultiFormatReader and GenericMultipleBarcodeReader.

  1. Call the decode method

The inconvenient part with ZXing is we have to convert BufferedImage to BinaryBitmap first:

BinaryBitmap bitmap = null;
int[] pixels = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth());
RGBLuminanceSource source = new RGBLuminanceSource(image.getWidth(), image.getHeight(), pixels);
bitmap = new BinaryBitmap(new HybridBinarizer(source));
            
MultiFormatReader reader = new MultiFormatReader();  
GenericMultipleBarcodeReader multiReader = new GenericMultipleBarcodeReader(reader);
        try {
            Result[] zxingResults = multiReader.decodeMultiple(bitmap);
        } catch (NotFoundException e) {
            e.printStackTrace();
        }
        pixels = null;
        bitmap = null;

Invoking Dynamsoft Barcode Reader method is much simpler as it supports BufferedImage as the input parameter:

BarcodeReader br = null;
        try {
            br = new BarcodeReader("LICENSE-KEY");
        } catch (Exception e) {
            System.out.println(e);
            return;
        }
        
        TextResult[] results = null;
        try {
            results = br.decodeBufferedImage(image, "");
        } catch (Exception e) {
            System.out.println("decode buffered image: " + e);
        }
  1. To run the Java program conveniently, we can assemble all dependencies into one jar file. Add the maven-assembly-plugin to pom.xml:
<build>
    <plugins>
      <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <configuration>
              <descriptorRefs>
                  <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
          </configuration>
      </plugin>
    </plugins>
  </build>

Build the Maven project:

mvn clean install assembly:assembly -Dmaven.test.skip=true

Run the Java barcode program as follows:

java -cp target/command-line-1.0-SNAPSHOT-jar-with-dependencies.jar 
com.java.barcode.App ..\images\AllSupportedBarcodeTypes.png
  1. Check the barcode decoding results.

Image 2

GUI Application

Based on the command-line Java barcode program created above, we can add Swing class to modify the command-line app to a GUI app.

Here are the relevant classes:

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JComboBox;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.filechooser.FileNameExtensionFilter;

import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

The widgets we need include JTextArea, JButton, JFileChooser and JComboBox.

  • JTextArea: display the results.
  • JButton: trigger the click event.
  • JFileChooser: select an image file from the disk drive.
  • JComboBox: toggle ZXing and Dynamsoft Barcode Reader.

Initialize the layout with all the widgets:

public App() {
        super(new BorderLayout());
        
        mFileChooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter(
                ".png", "png");
        mFileChooser.setFileFilter(filter);
        mLoad = new JButton("Load File");
        mLoad.addActionListener(this);
        
        mSourceList = new JComboBox(new String[]{"ZXing", "Dynamsoft"});
        mSourceList.setSelectedIndex(0);
        
        JPanel buttonPanel = new JPanel(); 
        buttonPanel.add(mSourceList);
        buttonPanel.add(mLoad);
        add(buttonPanel, BorderLayout.PAGE_START);
        
        mTextArea = new JTextArea();
        mTextArea.setSize(480, 480);
        JScrollPane sp = new JScrollPane(mTextArea); 
        add(sp, BorderLayout.CENTER);
    }

Select an image and decode barcodes by clicking the button:

public void actionPerformed(ActionEvent e) {

        int returnVal = mFileChooser.showOpenDialog(App.this);
 
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = mFileChooser.getSelectedFile();     
            String filename = file.toPath().toString();          
            if (mSourceList.getSelectedItem().toString().equals("Dynamsoft")) {
                TextResult[] results = decodefileDynamsoft(filename);
            }
            else {
                Result[] results = decodefileZXing(filename);
            }
        } 
    }

Build and run the GUI app:

mvn clean install assembly:assembly -Dmaven.test.skip=true
java -cp target/gui-1.0-SNAPSHOT-jar-with-dependencies.jar com.java.barcode.App

Image 3

Web Application

Spring Boot is used to create web apps. We can follow the official tutorial to get started with a simple web app.

To quickly test the server-side Java barcode APIs, we can integrate swagger-ui into the Spring Boot app by adding the following dependencies:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-core</artifactId>
    <version>1.1.45</version>
    <exclusions>
        <exclusion>
            <groupId>io.github.classgraph</groupId>
            <artifactId>classgraph</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.1.45</version>
</dependency>

Create a controller that contains POST mappings for ZXing and Dynamsoft Barcode Reader:

@RestController
public class BarcodeController {

    private DynamsoftBarcode mDynamsoftBarcode;
    private ZXingBarcode mZXingBarcode;

    @Autowired
    public BarcodeController(DynamsoftBarcode dynamsoft, ZXingBarcode zxing) {
        mDynamsoftBarcode = dynamsoft;
        mZXingBarcode = zxing;
    }

    @PostMapping(value = "/api/dynamsoft"
            , consumes = MediaType.MULTIPART_FORM_DATA_VALUE
            , produces = MediaType.APPLICATION_JSON_VALUE)
    public BarcodeResponse getDynamsoft(@RequestPart MultipartFile file) throws Exception {
        return mDynamsoftBarcode.decode(file.getOriginalFilename(), file.getInputStream());
    }

    @PostMapping(value = "/api/zxing"
            , consumes = MediaType.MULTIPART_FORM_DATA_VALUE
            , produces = MediaType.APPLICATION_JSON_VALUE)
    public BarcodeResponse getZXing(@RequestPart MultipartFile file) throws Exception {
        return mZXingBarcode.decode(file.getOriginalFilename(), file.getInputStream());
    }
}

Build and run the Java barcode web app:

mvn clean install
java -jar target/web-1.0-SNAPSHOT.jar

Visit http://localhost:8080/swagger-ui.html to test ZXing and Dynamsoft Barcode Reader via POST event.

Image 4

What about Android Development?

When developing mobile apps, we use Gradle instead of Maven to add the dependencies.

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url "http://download.dynamsoft.com/maven/dbr/aar"
        }
    }
}
implementation 'com.google.zxing:core:3.4.0'
implementation 'com.dynamsoft:dynamsoftbarcodereader:7.3.0'

Source Code

https://github.com/yushulx/java-barcode-command-gui-web

Technical Support

If you have any questions about the Dynamsoft Barcode Reader SDK, please feel free to contact us.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here