How to Build Desktop Barcode Scanner in Java and Kotlin
Tags: kotlin, gradle, java, barcode
Published: 2021-03-10 07:46:13

Dynamsoft provides Java Barcode SDKs for both mobile and desktop development. The mobile edition is distributed as an Android AAR package, and the desktop edition is distributed as a JAR package. This article aims to help developers who want to build desktop or server-side barcode scanner applications in Java or Kotlin. 


## Installing Dynamsoft Barcode Reader via Gradle

To get [Dynamsoft Barcode Reader](https://www.dynamsoft.com/barcode-reader/overview/), you can either [download the SDK](https://www.dynamsoft.com/barcode-reader/downloads) directly or configure the [Maven URL](http://download2.dynamsoft.com/maven/dbr/jar) for auto-build tools. I recommend using [Gradle](https://docs.gradle.org/current/userguide/userguide.html) to create a Java or Kotlin barcode scanner project. 

Here are the steps:

1. Create a new Gradle project:

    ```bash
    $ gradle init
    Select type of project to generate:
    1: basic
    2: application
    3: library
    4: Gradle plugin
    Enter selection (default: basic) [1..4] 

    Select implementation language:
    1: C++
    2: Groovy
    3: Java
    4: Kotlin
    5: Scala
    6: Swift
    Enter selection (default: Java) [1..6] 

    Split functionality across multiple subprojects?:
    1: no - only one application project
    2: yes - application and library projects
    Enter selection (default: no - only one application project) [1..2] 

    Select build script DSL:
    1: Groovy
    2: Kotlin
    Enter selection (default: Kotlin) [1..2] 
    ```


2. Go to **app > build.gradle** to add the Maven repository hosted by Dynamsoft and the dependency:


    ```groovy
    repositories {
        // Use JCenter for resolving dependencies.
        jcenter()
        maven {
            url "http://download2.dynamsoft.com/maven/dbr/jar"
        }
    }

    dependencies {
        // Use JUnit test framework.
        testImplementation 'junit:junit:4.13'

        // This dependency is used by the application.
        implementation 'com.google.guava:guava:29.0-jre'

        // Dynamsoft Barcode Reader SDK
        implementation 'com.dynamsoft:dbr:8.1.2'
    }
    ```


    **Note: for building Android barcode scanner projects, the URL and the package name are different:**


    ```groovy
    repositories {
        maven {
            url "http://download2.dynamsoft.com/maven/dbr/aar"
        }
    }

    dependencies {
        implementation 'com.dynamsoft:dynamsoftbarcodereader:latest.release@aar'
    }
    ```



## Java Barcode Scanner Application for Windows, Linux, and macOS

Dynamsoft Java Barcode SDK is implemented in Java Native Interface (JNI). Therefore, it brings better performance than pure Java SDKs, such as ZXing. Although the underlying technology is C++, the SDK has wrapped native libraries for multiple operating systems.

We can open **App.java** or **App.kt** files to instantiate the barcode reader object as follows:


```java
// Java
import com.dynamsoft.dbr.*;

BarcodeReader br = new BarcodeReader(license);
```

```kotlin
// Kotlin
import com.dynamsoft.dbr.*

val br = BarcodeReader(license)
```


Click [here](https://www.dynamsoft.com/customer/license/trialLicense) to get a **30-day FREE Trial License** if you want to unlock all API functionalities. 

Dynamsoft allows developers to custom algorithms for specific scenarios. So we can visit the [free barcode online demo](https://demo.dynamsoft.com/barcode-reader/) to generate an appropriate template for parameter initialization:


```java
// Java
br.initRuntimeSettingsWithString("{\"ImageParameter\":{\"Name\":\"Balance\",\"DeblurLevel\":5,\"ExpectedBarcodesCount\":512,\"LocalizationModes\":[{\"Mode\":\"LM_CONNECTED_BLOCKS\"},{\"Mode\":\"LM_STATISTICS\"}]}}", EnumConflictMode.CM_OVERWRITE);
```

```kotlin
// Kotlin
br.initRuntimeSettingsWithString("{\"ImageParameter\":{\"Name\":\"Balance\",\"DeblurLevel\":5,\"ExpectedBarcodesCount\":512,\"LocalizationModes\":[{\"Mode\":\"LM_CONNECTED_BLOCKS\"},{\"Mode\":\"LM_STATISTICS\"}]}}", EnumConflictMode.CM_OVERWRITE)
```


The following sample code is used to read barcodes from an image file and print out all results:

```java
// Java
results = mBarcodeReader.decodeFile(file, "");
for (TextResult result : results) {
    System.out.println(String.format("  Barcode %d:", index++));
    if(result.barcodeFormat != 0){
        System.out.println("    Type: " + result.barcodeFormatString);
    } else {
        System.out.println("    Type: " + result.barcodeFormatString_2);
    }


    System.out.println("    Value: " + result.barcodeText);

    System.out.println(String.format("    Region points: {(%d,%d),(%d,%d),(%d,%d),(%d,%d)}",
    result.localizationResult.resultPoints[0].x, result.localizationResult.resultPoints[0].y,
    result.localizationResult.resultPoints[1].x,result.localizationResult.resultPoints[1].y,
    result.localizationResult.resultPoints[2].x,result.localizationResult.resultPoints[2].y,
    result.localizationResult.resultPoints[3].x,result.localizationResult.resultPoints[3].y));
}
```

```kotlin
// Kotlin
val results: Array<TextResult> = br.decodeFile(file, "")
for (result in results) {
    println(String.format("  Barcode %d:", index++))
    if (result.barcodeFormat != 0) {
        System.out.println("    Type: " + result.barcodeFormatString)
    } else {
        System.out.println("    Type: " + result.barcodeFormatString_2)
    }
    System.out.println("    Value: " + result.barcodeText)
    println(
        java.lang.String.format(
            "    Region points: {(%d,%d),(%d,%d),(%d,%d),(%d,%d)}",
            result.localizationResult.resultPoints.get(0).x,
            result.localizationResult.resultPoints.get(0).y,
            result.localizationResult.resultPoints.get(1).x,
            result.localizationResult.resultPoints.get(1).y,
            result.localizationResult.resultPoints.get(2).x,
            result.localizationResult.resultPoints.get(2).y,
            result.localizationResult.resultPoints.get(3).x,
            result.localizationResult.resultPoints.get(3).y
        )
    )
}
```


With a few lines of code, a simple command-line barcode scanner is done. 

Here is a blurred QR code image:

![blurred QR code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uqbm9lznwvnw96y8mcy1.jpg)

We can now run the Gradle command with specified arguments.

```
./gradlew run --args="../../images/QR-Blurred.jpg ../../license.txt"
```

![Kotlin barcode scanner](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5msucpyyqjfmn3mx325.png)


## Testing Java Applications Using Travis CI

To verify whether the bar code scanner application is cross-platform, we create a **.travis.yml** file for the GitHub repository:


```yaml
language: java

jobs:
  include:
    - name: "Linux"
      os: linux
    - name: "macOS"
      os: osx
    - name: "Windows"
      os: windows           
      language: shell       
      before_install:
        - choco install jdk8 -params 'installdir=c:\\jdk' -y;
        - export JAVA_HOME=${JAVA_HOME:-/c/jdk};
      env: PATH=/c/jdk/bin:$PATH

branches:
  only:
    - main

script:
  - if [[ ${TRAVIS_OS_NAME} != "windows" ]]; then
        chmod +x java/gradlew;
        chmod +x kotlin/gradlew;
    fi
  - cd java
  - ./gradlew test
  - ./gradlew run --args="../../images/AllSupportedBarcodeTypes.png"
  - cd .. 
  - cd kotlin
  - ./gradlew test
  - ./gradlew run --args="../../images/AllSupportedBarcodeTypes.png"
```


We have to add '`chmod +x`' to make the `gradlew` script file work on Linux and macOS. 


## Source Code

[https://github.com/yushulx/gradle-java-kotlin-barcode-sample](https://github.com/yushulx/gradle-java-kotlin-barcode-sample)