How to Build DotCode Reader in Java on Windows 10

A dot code is a 2D barcode symbology composed of disconnected dots. It is widely used in the tobacco industry. Recently, Dynamsoft rolled out barcode reader SDK v7.4, which added DotCode support. In this post, I will share a command-line app and a GUI app, demonstrating how to build Java DotCode reader on Windows 10.

Decoding DotCode in Java Command-Line App

The command-line app is simple. What I am going to do is to invoke an API to decode DotCode from an image file.

Configure Dynamsoft Barcode Reader in pom.xml:


To simply the running command, we can add a plugin to assemble all dependencies into one jar file:


Instantiate Dynamsoft Barcode Reader and set DotCode as the target barcode:

        BarcodeReader br = null;
        try {
            br = new BarcodeReader("DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==");
            br.initRuntimeSettingsWithString("{\"ImageParameter\":{\"Name\":\"BestCoverage\",\"DeblurLevel\":9,\"ExpectedBarcodesCount\":512,\"ScaleDownThreshold\":100000,\"LocalizationModes\":[{\"Mode\":\"LM_CONNECTED_BLOCKS\"},{\"Mode\":\"LM_SCAN_DIRECTLY\"},{\"Mode\":\"LM_STATISTICS\"},{\"Mode\":\"LM_LINES\"},{\"Mode\":\"LM_STATISTICS_MARKS\"}],\"GrayscaleTransformationModes\":[{\"Mode\":\"GTM_ORIGINAL\"},{\"Mode\":\"GTM_INVERTED\"}]}}", EnumConflictMode.CM_OVERWRITE);
            PublicRuntimeSettings runtimeSettings = br.getRuntimeSettings();
            runtimeSettings.barcodeFormatIds_2 = EnumBarcodeFormat_2.BF2_DOTCODE;
        } catch (Exception e) {

By default, the SDK will decode all supported barcode formats. If you want to focus on DotCode and speed up the decoding process, disable other 1D and 2D barcode formats:

runtimeSettings.barcodeFormatIds = EnumBarcodeFormat.BF_NULL;

Pass the file path to the decodeFile() function which will soon return the barcode results:

        TextResult[] results = null;
        try {
            results = br.decodeFile(filename, "");
        } catch (Exception e) {
            System.out.println("decode buffered image: " + e);

Build and run the project:

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

java -cp target/command-line-dotcode-1.0-SNAPSHOT-jar-with-dependencies.jar test.png

A Webcam DotCode Reader Built with OpenCV Java and Java Swing

A GUI app needs more effort.

How to install OpenCV Java?

The OpenCV Java SDK contains a jar package and a shared library. For Windows users, you just need to install the pre-built package and find the OpenCV Java SDK at opencv-4.3\opencv\build\java. Since I’m using a Maven project, I have to install the jar file to the Maven local repository beforehand:

mvn install:install-file -Dfile=opencv-430.jar -DgroupId=org -DartifactId=opencv -Dversion=4.3.0 -Dpackaging=jar

Thereafter, add the configuration to pom.xml:


What about the dll file? If you don’t put the dll in the right place, you will get the error log as loading the library:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java430 in java.library.path
        at java.lang.ClassLoader.loadLibrary(
        at java.lang.Runtime.loadLibrary0(
        at java.lang.System.loadLibrary(

Here are the workarounds for the issue.

Check the available java library path. Copy the dll file to current working directory or add the dll path to system environment PATH:


Use the full path to load the library:


Define the Java library path when running your Java app:

java -Djava.library.path=<dll path> -cp target/opencv-dotcode-1.0-SNAPSHOT-jar-with-dependencies.jar

A “hello world” program using OpenCV Java

Once OpenCV is ready, you can test the library as follows:

Mat mat = Mat.eye(3, 3, CvType.CV_8UC1);
System.out.println("mat = " + mat.dump());

Display Webcam video stream in Java Swing component

Inspired by the OpenCV Java docs that guide JavaFX programming, I studied the OpenCV capture logic and rendered the video frames in a JLable:

public void updateViewer(final BufferedImage image) {
        if (!SwingUtilities.isEventDispatchThread()) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    mImage.setIcon(new ImageIcon(image));

Runnable frameGrabber = new Runnable() {

                    public void run() {
                        Mat frame = grabFrame();
                        byte[] data = Utils.matToByteArray(frame);

                        if (!status.get()) {
                            barcodeTimer.schedule(new BarcodeRunnable(frame, mBarcodeReader, callback, status), 0, TimeUnit.MILLISECONDS);
                        BufferedImage bufferedImage = Utils.byteToBufferedImage(data, frame.width(), frame.height(), frame.channels());
                        if (isRunning) updateViewer(bufferedImage);
this.timer = Executors.newSingleThreadScheduledExecutor();
this.timer.scheduleAtFixedRate(frameGrabber, 0, 33, TimeUnit.MILLISECONDS);

Read DotCode and show results

In the code above, you can see I created a barcode timer instance for reading DotCode:

barcodeTimer = Executors.newSingleThreadScheduledExecutor();

We have to run the barcode decoding API in a worker thread in order to avoid decreasing the frame rate.

To draw the DotCode position, create a class CustomJLable that extends JLable:

    private ArrayList<Point[]> data = new ArrayList<>();

    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        if (data.size() > 0) {
            for (Point[] points : data) {
                for (int i = 0; i < points.length; ++i) {
                    if (i == 3) {
                        g2d.drawLine(points[i].x, points[i].y, points[0].x, points[0].y);
                    } else {
                        g2d.drawLine(points[i].x, points[i].y, points[i + 1].x, points[i + 1].y);


    public void appendPoints(Point[] points) {

    public void clearPoints() {

Build and run the GUI DotCode reader:

mvn clean install assembly:assembly -Dmaven.test.skip=true
java -cp target/opencv-dotcode-1.0-SNAPSHOT-jar-with-dependencies.jar

Java DotCode reader


How to convert OpenCV Mat to Java byte array?

    public static byte[] matToByteArray(Mat original)
        int width = original.width(), height = original.height(), channels = original.channels();
        byte[] sourcePixels = new byte[width * height * channels];
        original.get(0, 0, sourcePixels);
        return sourcePixels;

How to convert Java byte array to Java BufferedImage?

    public static BufferedImage byteToBufferedImage(byte[] sourcePixels, int width, int height, int channels)
        BufferedImage image = null;
        if (channels > 1)
            image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
            image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
        final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
        System.arraycopy(sourcePixels, 0, targetPixels, 0, sourcePixels.length);
        return image;

Source Code