How to Build an HTML Page to Scan DotCode

DotCode is two-dimensional (2D) matrix barcode mainly used in the tobacco industry with advantages like the ability to apply the barcode by high-speed industrial printers and other methods like laser engraving.

Below is a pack of cigarettes with a DotCode representing its unique identifier.

cigarette pack

In this article, we are going to build an HTML page to scan DotCode using the JavaScript edition of Dynamsoft Barcode Reader.

Prerequisites

Get your trial key.

New HTML File

Create a new HTML file with the following template:

<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>DotCode Scanner</title>
  <style>
  h2 {
    text-align: center;
  }

  #app {
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  #cameraView {
    width: 100%;
    height: 60vh;
  }
  </style>
</head>
<html>
<body>
  <div id="app">
    <h2>DotCode Scanner</h2>
    <button id="startScanBtn">Start Scanning</button>
    <button id="readFromImageBtn">Read from an Image</button>
    <input id="fileInput" type="file" style="display:none;"/>
    <div id="status">Loading...</div>
    <div id="cameraView"></div>
    <div id="result"></div>
  </div>
</body>
</html>

Add Dynamsoft Barcode Reader

Include the library of Dynamsoft Barcode Reader with the following line of code:

<script src="https://cdn.jsdelivr.net/npm/dynamsoft-barcode-reader-bundle@10.4.2000/dist/dbr.bundle.js"></script>

Initialize Dynamsoft Barcode Reader

  1. Initialize the license. You can apply for a license here.

    Dynamsoft.License.LicenseManager.initLicense("LICENSE-KEY");
    
  2. Load the WASM file.

    Dynamsoft.Core.CoreModule.loadWasm(["dbr"]);
    
  3. Create an instance of Capture Vision Router to call Dynamsoft Barcode Reader.

    let cvRouter = await Dynamsoft.CVR.CaptureVisionRouter.createInstance();
    

Update the Settings to Scan DotCode

  1. Create a new JSON file named dotcode-template.json with the following content. It contains the configuration to scan DotCode.

    {
      "CaptureVisionTemplates": [
        {
          "Name": "Dotcode",
          "ImageROIProcessingNameArray": [
            "roi_read_dotcode"
          ],
          "Timeout": 700,
          "MaxParallelTasks":0
        }
      ],
      "TargetROIDefOptions": [
        {
          "Name": "roi_read_dotcode",
          "TaskSettingNameArray": [
            "task_read_dotcode"
          ]
        }
      ],
      "BarcodeFormatSpecificationOptions": [
        {
          "Name": "format_specification_read_dotcode",
          "BarcodeFormatIds": [
            "BF_DOTCODE"
          ],
          "MirrorMode": "MM_BOTH"
        }
      ],
      "BarcodeReaderTaskSettingOptions": [
        {
          "Name": "task_read_dotcode",
          "ExpectedBarcodesCount" : 1,
          "BarcodeFormatIds" : [ "BF_DOTCODE" ],
          "LocalizationModes": [
            {
              "Mode" : "LM_STATISTICS_MARKS"
            }
          ],
          "DeblurModes":
          [
            {
              "Mode": "DM_BASED_ON_LOC_BIN"
            },
            {
              "Mode": "DM_THRESHOLD_BINARIZATION"
            },
            {
              "Mode": "DM_DEEP_ANALYSIS"
            }
          ],
          "BarcodeFormatSpecificationNameArray": [
            "format_specification_read_dotcode"
          ],
          "SectionImageParameterArray": [
            {
              "Section": "ST_REGION_PREDETECTION",
              "ImageParameterName": "ip_read_dotcode"
            },
            {
              "Section": "ST_BARCODE_LOCALIZATION",
              "ImageParameterName": "ip_read_dotcode"
            },
            {
              "Section": "ST_BARCODE_DECODING",
              "ImageParameterName": "ip_read_dotcode"
            }
          ]
        }
      ],
      "ImageParameterOptions": [
        {
          "Name": "ip_read_dotcode",
          "BinarizationModes": [
            {
              "Mode": "BM_LOCAL_BLOCK",
              "BlockSizeX": 15,
              "BlockSizeY": 15,
              "EnableFillBinaryVacancy": 0,
              "ThresholdCompensation": 10
            },
            {
              "Mode": "BM_LOCAL_BLOCK",
              "BlockSizeX": 21,
              "BlockSizeY": 21,
              "EnableFillBinaryVacancy": 0,
              "ThresholdCompensation": 10,
              "MorphOperation":"Erode",
              "MorphOperationKernelSizeX":3,
              "MorphOperationKernelSizeY":3,
              "MorphShape":"Ellipse"
            },
            {
              "Mode": "BM_LOCAL_BLOCK",
              "BlockSizeX": 35,
              "BlockSizeY": 35,
              "EnableFillBinaryVacancy": 0,
              "ThresholdCompensation": 10,
              "MorphOperation":"Erode",
              "MorphOperationKernelSizeX":3,
              "MorphOperationKernelSizeY":3,
              "MorphShape":"Ellipse"
            },
            {
              "Mode": "BM_LOCAL_BLOCK",
              "BlockSizeX": 45,
              "BlockSizeY": 45,
              "EnableFillBinaryVacancy": 0,
              "ThresholdCompensation": 25,
              "MorphOperation":"Erode",
              "MorphOperationKernelSizeX":3,
              "MorphOperationKernelSizeY":3,
              "MorphShape":"Ellipse"
            }
          ],
          "GrayscaleEnhancementModes": [
            {
              "Mode": "GEM_GENERAL"
            }
          ],
          "GrayscaleTransformationModes": [
            {
              "Mode": "GTM_INVERTED"
            },
            {
              "Mode": "GTM_ORIGINAL"
            }
          ]
        }
      ]
    }
    

    We can see that it is related to image processing. For example, the DotCode on cigarettes is often inverted, so we can set GrayscaleTransformationModes to read the inverted image first. You can learn more about how Dynamsoft Barcode Reader handles DotCode on this page.

  2. Use the template file.

    await cvRouter.initSettings("./dotcode-template.json");
    
  3. Set up a scan region so that the barcode reader will only process a part of the frame. It can improve the success rate of barcode localization. The code to initialize Camera Enhancer is in the next part.

    await cameraEnhancer.setScanRegion({
      x: 1,
      y: 40,
      width: 98,
      height: 20,
      isMeasuredInPercentage: true,
    });
    

Start Scanning from the Camera

  1. Initialize Camera Enhancer and bind its viewer to a container.

    let cameraView = await Dynamsoft.DCE.CameraView.createInstance();
    let cameraEnhancer = await Dynamsoft.DCE.CameraEnhancer.createInstance(cameraView);
    document.querySelector("#cameraView").append(cameraView.getUIElement());
    
  2. Use Camera Enhancer as the input of the capture vision router so that it can fetch frames from the cameras for reading barcodes.

    cvRouter.setInput(cameraEnhancer);
    
  3. Add a filter to enable multiple frames verification to make sure that the barcode result is correct and to avoid reading the same barcodes too quickly. (Optional)

    let filter = new Dynamsoft.Utility.MultiFrameResultCrossFilter();
    filter.enableResultCrossVerification("barcode", true);
    filter.enableResultDeduplication("barcode", true);
    await cvRouter.addResultFilter(filter);
    
  4. Add a result receiver to receive the scanning results.

    cvRouter.addResultReceiver({ onDecodedBarcodesReceived: (result) => {
      displayResults(result);
    }});
    
    function displayResults(result){
      if (result.barcodeResultItems.length > 0) {
        let container = document.getElementById("result");
        let item = result.barcodeResultItems[0];
        container.innerText = `${item.formatString}: ${item.text}`;
      }
    }
    
  5. Start scanning after the scan button is clicked.

    let templateName = "Dotcode"
    await cameraEnhancer.open();
    await cvRouter.startCapturing(templateName);
    

Read DotCode in an Image

Apart from live scanning, we can also read DotCode in an image.

Add events for selecting an image file. After the image is selected, read the barcodes in it using the capture method.

document.getElementById("readFromImageBtn").addEventListener("click",function(){
  if (initialized) {
    document.getElementById("fileInput").click();
  }else{
    alert("Please wait for the initialization.");
  }
});
document.getElementById("fileInput").addEventListener("change",async function(){
  let files = document.getElementById("fileInput").files;
  if (files.length>0) {
    let file  = files[0];
    let result = await cvRouter.capture(file,templateName);
    displayResults(result);
  }
})

All right, we’ve finished the demo.

Source Code

Check out the source code to have a try:

https://github.com/tony-xlh/DotCode-Scanner-JS