| name | dbr-python-sample-creator |
| description | Use when implementing Python sample code using the Dynamsoft Barcode Reader SDK (`dynamsoft_barcode_reader_bundle` package). This skill covers all barcode reading use cases including 1D barcodes, QR codes, PDF417, DataMatrix, DPM barcodes, and any other barcode decoding scenario built on the DBR Python Edition. Use this skill whenever the user mentions Dynamsoft Barcode Reader, DBR, `dynamsoft_barcode_reader_bundle`, `CaptureVisionRouter` for barcode reading, barcode scanning with Dynamsoft, barcode decoding, or wants to create a Python sample that processes images to extract barcodes.
|
DBR Python Sample Creator
This skill helps you write Python sample code using the dynamsoft_barcode_reader_bundle SDK. The SDK provides a pipeline for barcode reading — orchestrated through a single central class called CaptureVisionRouter.
Before you start
read the appropriate reference files from the references/ directory alongside this SKILL.md to understand the API you're working with. The references are organized by module — only read what you need for the task at hand:
| Reference file | When to read |
|---|
references/api-core.md | Always — contains foundational types, enums, geometry, ImageData, error codes |
references/api-cvr.md | Always — CaptureVisionRouter, templates, settings, result receivers |
references/api-dbr.md | Always — barcode reading API, barcode formats, result items, settings |
references/api-utility.md | When the task involves batch processing, video, cross-frame filtering, or image I/O |
references/api-license.md | Always — license initialization |
references/sample-patterns.md | Always — canonical code patterns extracted from existing samples |
SDK Architecture Overview
The SDK follows a pipeline architecture centered around CaptureVisionRouter:
Image Input → CaptureVisionRouter (with template) → CapturedResult
└── DecodedBarcodesResult
Key concepts:
- CaptureVisionRouter — The central orchestrator. Create an instance, optionally configure settings/templates, then call
capture() or capture_multi_pages() to process images.
- Templates — Define what the pipeline does. Use
EnumPresetTemplate constants for common tasks, or load custom JSON templates for specialized scenarios.
- Results — Processing returns a
CapturedResult (single image) or CapturedResultArray (multi-page). Extract barcode results using get_decoded_barcodes_result().
Writing Samples: Step by Step
Every DBR Python sample follows this structure. Understanding this flow is essential because deviating from it leads to subtle bugs — for instance, forgetting to check the license error code will cause silent failures.
Step 1: Import
Always use the wildcard import — the package re-exports everything from all submodules:
from dynamsoft_barcode_reader_bundle import *
For additional libraries (os, sys, cv2, Flask, etc.), import them separately as needed.
Step 2: Initialize License
License initialization must happen once, before creating any CaptureVisionRouter instance. The SDK returns a tuple of (error_code, error_message).
License string priority: Default hard-coded license string is "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTEwNTI2NzQwMSJ9".
Required comment block: Every sample must include this 3-line comment block immediately before the init_license call. This comment is mandatory — never omit it. Adjust the quoted license string in the third line to match whichever license string is actually used in the code:
Full license initialization pattern:
error_code, error_msg = LicenseManager.init_license("DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTEwNTI2NzQwMSJ9")
if error_code != EnumErrorCode.EC_OK and error_code != EnumErrorCode.EC_LICENSE_WARNING:
print("License initialization failed: ErrorCode:", error_code, ", ErrorString:", error_msg)
else:
...
Check against both EC_OK and EC_LICENSE_WARNING (warnings are non-fatal).
Step 3: Create CaptureVisionRouter
cvr_instance = CaptureVisionRouter()
No arguments needed. If using a custom JSON template, load it right after:
error_code, error_msg = cvr_instance.init_settings_from_file("path/to/template.json")
if error_code != EnumErrorCode.EC_OK:
print("Init template failed:", error_msg)
Step 4: Process Images
There are three processing paradigms. Choose based on the use case:
A. Single-shot capture (simplest, for one image at a time)
result = cvr_instance.capture(image_path, EnumPresetTemplate.PT_READ_BARCODES)
The capture() method accepts multiple input types:
str — file path
bytes — file bytes in memory
ImageData — SDK's own image class
numpy.ndarray — OpenCV/PIL array (BGR format from OpenCV, RGB from PIL)
B. Multi-page capture (for PDFs, TIFFs, or any file)
result_array = cvr_instance.capture_multi_pages(image_path, EnumPresetTemplate.PT_READ_BARCODES)
results = result_array.get_results()
for i, result in enumerate(results):
...
This is the preferred method for file-based processing because it handles multi-page files correctly. Even for single-page images it works fine — you'll just get one result.
C. Continuous/streaming capture (for video or batch directories)
This uses the observer pattern with ImageSourceAdapter, CapturedResultReceiver, and optionally ImageSourceStateListener:
fetcher = DirectoryFetcher()
fetcher.set_directory("path/to/images")
cvr_instance.set_input(fetcher)
receiver = MyCapturedResultReceiver()
cvr_instance.add_result_receiver(receiver)
listener = MyImageSourceStateListener(cvr_instance)
cvr_instance.add_image_source_state_listener(listener)
cvr_instance.start_capturing(EnumPresetTemplate.PT_READ_BARCODES, True)
Step 5: Extract Results
After capturing, extract barcode results. Always check for errors first:
if result.get_error_code() != EnumErrorCode.EC_OK:
print("Error:", result.get_error_code(), result.get_error_string())
Note: EC_UNSUPPORTED_JSON_KEY_WARNING is a warning, not a fatal error — print a warning but continue processing.
Barcode results:
barcode_result = result.get_decoded_barcodes_result()
if barcode_result is not None and barcode_result.get_items() != 0:
for item in barcode_result.get_items():
print("Format:", item.get_format_string())
print("Text:", item.get_text())
Preset Templates Quick Reference
| Template | Use for |
|---|
PT_READ_BARCODES | General barcode reading |
PT_READ_BARCODES_SPEED_FIRST | Fast barcode reading (sacrifices accuracy) |
PT_READ_BARCODES_READ_RATE_FIRST | Max accuracy barcode reading |
PT_READ_SINGLE_BARCODE | Optimized for exactly one barcode |
Custom JSON Templates
When preset templates don't meet requirements, create a custom JSON template. The template structure has these top-level arrays:
{
"CaptureVisionTemplates": [...],
"TargetROIDefOptions": [...],
"BarcodeReaderTaskSettingOptions": [...],
"ImageParameterOptions": [...],
"BarcodeFormatSpecificationOptions": [...]
}
Load custom templates with:
cvr_instance.init_settings_from_file("path/to/template.json")
result = cvr_instance.capture(image, "TemplateName")
Settings Customization via API
For simpler adjustments (without JSON templates), use the simplified settings API:
err_code, err_str, settings = cvr_instance.get_simplified_settings(EnumPresetTemplate.PT_READ_BARCODES)
settings.barcode_settings.barcode_format_ids = EnumBarcodeFormat.BF_QR_CODE | EnumBarcodeFormat.BF_PDF417
settings.barcode_settings.expected_barcodes_count = 10
settings.barcode_settings.grayscale_transformation_modes[0] = EnumGrayscaleTransformationMode.GTM_AUTO
settings.roi_measured_in_percentage = 1
points = settings.roi.points
points[0].x, points[0].y = 0, 0
points[1].x, points[1].y = 100, 0
points[2].x, points[2].y = 100, 100
points[3].x, points[3].y = 0, 100
cvr_instance.update_settings(EnumPresetTemplate.PT_READ_BARCODES, settings)
Multi-page Result Handling
When using capture_multi_pages(), results come as a CapturedResultArray. Use this pattern to handle page numbers correctly:
result_array = cvr_instance.capture_multi_pages(image_path, template)
results = result_array.get_results()
if results is None or len(results) == 0:
print("No results.")
else:
for i, result in enumerate(results):
page_number = i + 1
tag = result.get_original_image_tag()
if isinstance(tag, FileImageTag):
page_number = tag.get_page_number() + 1
if result.get_error_code() == EnumErrorCode.EC_UNSUPPORTED_JSON_KEY_WARNING:
print("Warning:", result.get_error_code(), result.get_error_string())
elif result.get_error_code() != EnumErrorCode.EC_OK:
print("Error:", result.get_error_code(), result.get_error_string())
Advanced Patterns
Video/Camera Decoding
For real-time video, subclass ImageSourceAdapter to feed frames, and use CapturedResultReceiver for async results. Also consider MultiFrameResultCrossFilter for deduplication:
class MyVideoFetcher(ImageSourceAdapter):
def has_next_image_to_fetch(self) -> bool:
return True
fetcher = MyVideoFetcher()
fetcher.set_max_image_count(100)
fetcher.set_buffer_overflow_protection_mode(EnumBufferOverflowProtectionMode.BOPM_UPDATE)
fetcher.set_colour_channel_usage_type(EnumColourChannelUsageType.CCUT_AUTO)
cvr_instance.set_input(fetcher)
filter = MultiFrameResultCrossFilter()
filter.enable_result_cross_verification(EnumCapturedResultItemType.CRIT_BARCODE, True)
filter.enable_result_deduplication(EnumCapturedResultItemType.CRIT_BARCODE, True)
filter.set_duplicate_forget_time(EnumCapturedResultItemType.CRIT_BARCODE, 5000)
cvr_instance.add_result_filter(filter)
tag = FileImageTag("", 0, 0)
tag.set_image_id(image_id)
image = ImageData(frame.tobytes(), width, height, stride, EnumImagePixelFormat.IPF_RGB_888, 0, tag)
fetcher.add_image_to_buffer(image)
Intermediate Results
For advanced scenarios like visualizing barcode localization vs decoding, use IntermediateResultReceiver:
class MyIRR(IntermediateResultReceiver):
def on_localized_barcodes_received(self, result, info):
if info.is_section_level_result:
for i in range(result.get_count()):
element = result.get_localized_barcode(i)
location = element.get_location()
irm = cvr_instance.get_intermediate_result_manager()
irr = MyIRR()
irm.add_result_receiver(irr)
Image I/O and Drawing
io = ImageIO()
err, image = io.read_from_file("input.png")
io.save_to_file(image_data, "output.png")
drawer = ImageDrawer()
image = drawer.draw_on_image(image, quadrilaterals, 0xFF00FF00, 2)
Server-Side (Flask)
For web service integration, create a new CaptureVisionRouter() per request (or use a singleton with thread safety). Accept images via multipart, JSON (base64), or raw binary:
from flask import Flask, request, jsonify
@app.route('/decode', methods=['POST'])
def decode():
data = request.files['file'].read()
cvr = CaptureVisionRouter()
result = cvr.capture(data, EnumPresetTemplate.PT_READ_BARCODES)
Code Style Conventions
Follow these conventions to produce samples consistent with the existing codebase:
- Use
if __name__ == '__main__': as the entry point
- Use numbered comments like
# 1. Initialize license. for major steps
- Print informative messages including error codes and descriptions
- End with
input("Press Enter to quit...") for interactive CLI samples
- Use
Path(__file__).resolve().parent for relative path resolution
- Handle both
EC_OK and EC_LICENSE_WARNING / EC_UNSUPPORTED_JSON_KEY_WARNING where appropriate
- For interactive samples, support loop with quit option (
'Q'/'q')