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.
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.
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
- Create a new Maven project:
mvn archetype:generate -DgroupId=com.java.barcode -DartifactId=app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
- 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.*;
- 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;
}
- 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
.
- 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);
}
- 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
- Check the barcode decoding results.
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
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.
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.