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:
<repositories> <repository> <id>dbr</id> <url>https://download2.dynamsoft.com/maven/dbr/jar</url> </repository> </repositories> <dependencies> <dependency> <groupId>com.dynamsoft</groupId> <artifactId>dbr</artifactId> <version>7.4.0</version> </dependency> </dependencies>
To simply the running command, we can add a plugin to assemble all dependencies into one jar file:
<build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> </plugins> </build>
Instantiate Dynamsoft Barcode Reader and set DotCode as the target barcode:
BarcodeReader br = null; try { br = new BarcodeReader("LICENSE-KEY"); 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; br.updateRuntimeSettings(runtimeSettings); } catch (Exception e) { System.out.println(e); return; }
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 com.java.barcode.App 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:
<dependency> <groupId>org</groupId> <artifactId>opencv</artifactId> <version>4.3.0</version> </dependency>
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(ClassLoader.java:1867) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at com.java.barcode.App.main(App.java:65)
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:
System.out.println(System.getProperty("java.library.path"));
Use the full path to load the library:
System.load("D:/opencv-4.3/opencv/build/java/x64/opencv_java430.dll");
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 com.java.barcode.App
A “hello world” program using OpenCV Java
Once OpenCV is ready, you can test the library as follows:
System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 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() { @Override public void run() { mImage.setIcon(new ImageIcon(image)); } }); return; } } Runnable frameGrabber = new Runnable() { @Override public void run() { Mat frame = grabFrame(); byte[] data = Utils.matToByteArray(frame); if (!status.get()) { status.set(true); 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<>(); @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); if (data.size() > 0) { g2d.setColor(Color.RED); 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); } } } } g2d.dispose(); } public void appendPoints(Point[] points) { data.add(points); } public void clearPoints() { data.clear(); }
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 com.java.barcode.App

Q&A
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); } else { 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
https://github.com/yushulx/java-dotcode-reader
The post How to Build DotCode Reader in Java on Windows 10 appeared first on Code Pool.