diff --git a/README.md b/README.md
index b8d8aaed..68dacb7a 100644
--- a/README.md
+++ b/README.md
@@ -174,6 +174,7 @@ If you have any questions, feel free to [contact Dynamsoft support](https://www.
- [scan-1D-Industrial/](./scenarios/scan-1D-Industrial/) — 1D industrial barcode tuning example.
- [scan-from-distance/](./scenarios/scan-from-distance/) — Demo for scanning barcodes from a distance (zoom/ROI tuning).
- [locate-an-item-with-barcode/](./scenarios/locate-an-item-with-barcode/) — UI to help locate items with barcodes in a list or layout.
+- [grid-barcode-reading/](./scenarios/grid-barcode-reading/) — Scan a grid of DataMatrix / QR codes from an uploaded image with fast scan, layout analysis, and deep decode.
- [debug/](./scenarios/debug/) — Debug utilities and a small server (frame collector) used for testing and troubleshooting.
### Official Online Demo
diff --git a/index.html b/index.html
index 333bdc73..92143312 100644
--- a/index.html
+++ b/index.html
@@ -1071,7 +1071,7 @@
diff --git a/scenarios/README.md b/scenarios/README.md
index 35e6ce6e..048ab472 100644
--- a/scenarios/README.md
+++ b/scenarios/README.md
@@ -22,6 +22,7 @@ Included samples
- [scan-1D-Industrial/](./scan-1D-Industrial/) — 1D industrial barcode tuning example.
- [scan-from-distance/](./scan-from-distance/) — Demo for scanning barcodes from a distance (zoom/ROI tuning).
- [locate-an-item-with-barcode/](./locate-an-item-with-barcode/) — UI to help locate items with barcodes in a list or layout.
+- [grid-barcode-reading/](./grid-barcode-reading/) — Scan a grid of DataMatrix / QR codes from an uploaded image with fast scan, layout analysis, and deep decode.
- [debug/](./debug/) — Debug utilities and a small server (frame collector) used for testing and troubleshooting.
>[!NOTE]
diff --git a/scenarios/grid-barcode-reading/GridDeepDecode.json b/scenarios/grid-barcode-reading/GridDeepDecode.json
new file mode 100644
index 00000000..e2cc067b
--- /dev/null
+++ b/scenarios/grid-barcode-reading/GridDeepDecode.json
@@ -0,0 +1,150 @@
+{
+ "BarcodeFormatSpecificationOptions": [
+ {
+ "BarcodeFormatIds": [
+ "BF_DATAMATRIX", "BF_QR_CODE"
+ ],
+ "MirrorMode": "MM_BOTH",
+ "Name": "bfs1"
+ }
+ ],
+ "BarcodeReaderTaskSettingOptions": [
+ {
+ "BarcodeFormatIds": [
+ "BF_DATAMATRIX", "BF_QR_CODE"
+ ],
+ "BarcodeFormatSpecificationNameArray": [
+ "bfs1"
+ ],
+ "ExpectedBarcodesCount": 1,
+ "MaxThreadsInOneTask": 0,
+ "Name": "task-read-barcodes",
+ "SectionArray": [
+ {
+ "ImageParameterName": "ip-read-barcodes",
+ "Section": "ST_BARCODE_LOCALIZATION",
+ "StageArray": [
+ {
+ "Stage": "SST_LOCALIZE_CANDIDATE_BARCODES",
+ "LocalizationModes": [
+ {
+ "Mode": "LM_CONNECTED_BLOCKS"
+ },
+ {
+ "Mode": "LM_STATISTICS"
+ },
+ {
+ "Mode": "LM_LINES"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "ImageParameterName": "ip-read-barcodes",
+ "Section": "ST_BARCODE_DECODING",
+ "StageArray" :
+ [
+ {
+ "Stage" : "SST_RESIST_DEFORMATION"
+ },
+ {
+ "Stage" : "SST_COMPLEMENT_BARCODE"
+ },
+ {
+ "Stage" : "SST_SCALE_BARCODE_IMAGE"
+ },
+ {
+ "Stage" : "SST_DECODE_BARCODES",
+ "DeblurModes": [
+ {
+ "Mode": "DM_BASED_ON_LOC_BIN"
+ },
+ {
+ "Mode": "DM_THRESHOLD_BINARIZATION"
+ },
+ {
+ "Mode": "DM_DIRECT_BINARIZATION"
+ },
+ {
+ "Mode": "DM_NEURAL_NETWORK"
+ },
+ {
+ "Mode": "DM_DEEP_ANALYSIS"
+ },
+ {
+ "Mode": "DM_SMOOTHING"
+ },
+ {
+ "Mode": "DM_GRAY_EQUALIZATION"
+ },
+ {
+ "Mode": "DM_MORPHING"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "CaptureVisionTemplates": [
+ {
+ "ImageROIProcessingNameArray": [
+ "roi-read-barcodes"
+ ],
+ "Name": "GridDeepDecode",
+ "Timeout": 5000
+ }
+ ],
+ "ImageParameterOptions": [
+ {
+ "ApplicableStages": [
+ {
+ "GrayscaleTransformationModes": [
+ {
+ "Mode": "GTM_ORIGINAL"
+ },
+ {
+ "Mode": "GTM_INVERTED"
+ }
+ ],
+ "Stage": "SST_TRANSFORM_GRAYSCALE"
+ },
+ {
+ "GrayscaleEnhancementModes": [
+ {
+ "Mode": "GEM_GENERAL"
+ },
+ {
+ "Mode": "GEM_GRAY_SMOOTH"
+ }
+ ],
+ "Stage": "SST_ENHANCE_GRAYSCALE"
+ },
+ {
+ "BinarizationModes": [
+ {
+ "BlockSizeX": 0,
+ "BlockSizeY": 0,
+ "EnableFillBinaryVacancy": 0,
+ "ThresholdCompensation": 10,
+ "Mode": "BM_LOCAL_BLOCK"
+ }
+ ],
+ "Stage": "SST_BINARIZE_IMAGE"
+ }
+ ],
+ "Name": "ip-read-barcodes"
+ }
+ ],
+ "TargetROIDefOptions": [
+ {
+ "Name": "roi-read-barcodes",
+ "TaskSettingNameArray": [
+ "task-read-barcodes"
+ ]
+ }
+ ],
+ "Version": "5.3"
+}
\ No newline at end of file
diff --git a/scenarios/grid-barcode-reading/GridFastScan.json b/scenarios/grid-barcode-reading/GridFastScan.json
new file mode 100644
index 00000000..c5f99f37
--- /dev/null
+++ b/scenarios/grid-barcode-reading/GridFastScan.json
@@ -0,0 +1,101 @@
+{
+ "BarcodeFormatSpecificationOptions": [
+ {
+ "BarcodeFormatIds": [
+ "BF_DATAMATRIX", "BF_QR_CODE"
+ ],
+ "MirrorMode": "MM_BOTH",
+ "Name": "bfs1"
+ }
+ ],
+ "BarcodeReaderTaskSettingOptions": [
+ {
+ "BarcodeFormatIds": [
+ "BF_DATAMATRIX", "BF_QR_CODE"
+ ],
+ "BarcodeFormatSpecificationNameArray": [
+ "bfs1"
+ ],
+ "ExpectedBarcodesCount": 0,
+ "MaxThreadsInOneTask": 0,
+ "Name": "task-read-barcodes",
+ "SectionArray": [
+ {
+ "ImageParameterName": "ip-read-barcodes",
+ "Section": "ST_BARCODE_LOCALIZATION",
+ "StageArray": [
+ {
+ "Stage": "SST_LOCALIZE_CANDIDATE_BARCODES",
+ "LocalizationModes": [
+ {
+ "Mode": "LM_CONNECTED_BLOCKS"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "ImageParameterName": "ip-read-barcodes",
+ "Section": "ST_BARCODE_DECODING"
+ }
+ ]
+ }
+ ],
+ "CaptureVisionTemplates": [
+ {
+ "ImageROIProcessingNameArray": [
+ "roi-read-barcodes"
+ ],
+ "Name": "GridFastScan",
+ "Timeout": 10000,
+ "MaxParallelTasks": 4
+ }
+ ],
+ "ImageParameterOptions": [
+ {
+ "ApplicableStages": [
+ {
+ "Stage": "SST_SCALE_IMAGE",
+ "ImageScaleSetting":{
+ "ScaleType": "ST_SCALE_DOWN",
+ "ReferenceEdge": "RE_SHORTER_EDGE",
+ "EdgeLengthThreshold": 4000
+ }
+ },
+ {
+ "GrayscaleTransformationModes": [
+ {
+ "Mode": "GTM_ORIGINAL"
+ },
+ {
+ "Mode": "GTM_INVERTED"
+ }
+ ],
+ "Stage": "SST_TRANSFORM_GRAYSCALE"
+ },
+ {
+ "BinarizationModes": [
+ {
+ "BlockSizeX": 31,
+ "BlockSizeY": 31,
+ "EnableFillBinaryVacancy": 0,
+ "ThresholdCompensation": 10,
+ "Mode": "BM_LOCAL_BLOCK"
+ }
+ ],
+ "Stage": "SST_BINARIZE_IMAGE"
+ }
+ ],
+ "Name": "ip-read-barcodes"
+ }
+ ],
+ "TargetROIDefOptions": [
+ {
+ "Name": "roi-read-barcodes",
+ "TaskSettingNameArray": [
+ "task-read-barcodes"
+ ]
+ }
+ ],
+ "Version": "5.3"
+}
\ No newline at end of file
diff --git a/scenarios/grid-barcode-reading/README.md b/scenarios/grid-barcode-reading/README.md
new file mode 100644
index 00000000..ad2f4d66
--- /dev/null
+++ b/scenarios/grid-barcode-reading/README.md
@@ -0,0 +1,44 @@
+# 📊 Grid Barcode Reading
+
+A demo that scans a grid of DataMatrix / QR codes from an uploaded image. The scanner performs a fast scan, layout analysis, and deep decode to read every cell in the grid using the Dynamsoft Barcode Reader (JavaScript edition).
+
+## Included files
+
+- `index.html` — demo page (image upload + grid scanning UI).
+- `GridFastScan.json` — configuration for the initial fast scan pass.
+- `GridDeepDecode.json` — configuration for the deep decode pass on missed cells.
+- `sample_grid.png` — example grid image for testing.
+
+## ✨ Features
+
+- Image-based grid scanning (upload an image containing a grid of DataMatrix / QR codes)
+- Three-phase pipeline: fast scan → layout analysis → deep decode
+- Visual grid result table showing decoded text, status, and location for each cell
+- Statistics display (total cells, decoded count, success rate)
+
+## 🔧 How it works
+
+- **Phase 1 – Fast Scan**: The uploaded image is processed with `GridFastScan` settings to quickly decode as many barcodes as possible.
+- **Phase 2 – Layout Analysis**: A layout engine identifies the grid structure and maps decoded texts to their row/column positions.
+- **Phase 3 – Deep Decode**: Cells that failed in the fast scan are individually re-processed using `GridDeepDecode` settings with more aggressive decoding modes (deblur, morphing, neural network, etc.).
+- Results are rendered as an interactive grid table with color-coded status indicators.
+
+## Quick start
+
+Opening HTML files directly may not work as expected. Instead, run a local development server. Here's a quick method using [Visual Studio Code](https://code.visualstudio.com/):
+
+1. Install the [Five Server extension](https://marketplace.visualstudio.com/items?itemName=yandeu.five-server) from the VS Code Marketplace.
+
+2. Right-click on `index.html` and select "Open with Five Server".
+
+## 💡 Tips
+
+- Use high-resolution images for better grid detection accuracy.
+- The sample image `sample_grid.png` can be used for quick testing.
+- Adjust the JSON configurations to tune the balance between speed and accuracy.
+
+## 📌 Notes
+
+- Serve on localhost/HTTPS to avoid browser restrictions.
+- This demo processes static images (no camera required).
+- Replace the included demo/trial license with a valid Dynamsoft license for extended evaluation.
diff --git a/scenarios/grid-barcode-reading/index.html b/scenarios/grid-barcode-reading/index.html
new file mode 100644
index 00000000..ce4c55bb
--- /dev/null
+++ b/scenarios/grid-barcode-reading/index.html
@@ -0,0 +1,965 @@
+
+
+
+
+
+
+ Dynamsoft DataMatrix Grid Scanner
+
+
+
+
+
+
+
+
DataMatrix Grid Scanner
+
+ Upload an image to scan a grid of DataMatrix barcodes. The scanner performs fast scan, layout analysis, and deep decode to read
+ every cell in the grid.
+
+
+
+
+
+
+ No file selected
+
+
+
+
+
+
+ 0.0s
+
+
+
+
+
+ Fast Scan
+
+
+
+
+ Layout Analysis
+
+
+
+
+ Deep Decode
+
+
+
+
+ Final Result
+
+
+
+
+
+
+
+ Image preview will appear here after uploading
+
+
+
+
+
Results
+
+
+
+
+
+
Row
+
Col
+
Status
+
Text
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scenarios/grid-barcode-reading/sample_grid.png b/scenarios/grid-barcode-reading/sample_grid.png
new file mode 100644
index 00000000..27cb5c6d
Binary files /dev/null and b/scenarios/grid-barcode-reading/sample_grid.png differ