Skip to content

Commit 9c3975c

Browse files
committed
- Update the URL for requesting the trial license key
- Add a DBR v.10 example
1 parent 6f6c6db commit 9c3975c

File tree

21 files changed

+244
-22
lines changed

21 files changed

+244
-22
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ dist
44
/examples/official/9.x/zxing_zbar/__pycache__/*.pyc
55
/examples/official/9.x/jupyter_notebook/.ipynb_checkpoints
66
/examples/official/9.x/qt_gui/__pycache__/*.pyc
7+
.DS_Store

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
# Python Extension: Barcode and QR Code SDK
22
This project provides a CPython binding to the [Dynamsoft C/C++ Barcode Reader SDK v9.x](https://www.dynamsoft.com/barcode-reader/sdk-desktop-server/). It demonstrates how to build a **Python 1D/2D barcode SDK** package for `Windows`, `Linux` and `macOS` from scratch. Beyond desktop PCs, it's also compatible with embedded and IoT devices such as `Raspberry Pi` and `Jetson Nano`. You are **free** to customize the Python API for Dynamsoft Barcode Reader to suit your specific needs.
33

4-
> Note: This project is an unofficial, community-maintained Python wrapper for the Dynamsoft Barcode SDK. For those seeking the most reliable and fully-supported solution, Dynamsoft offers an official Python package. Visit the [Dynamsoft Barcode Reader](https://pypi.org/project/dbr/) page on PyPI for more details.
4+
> Note: This project is an unofficial, community-maintained Python wrapper for the Dynamsoft Barcode SDK. For those seeking the most reliable and fully-supported solution, Dynamsoft offers an official Python package. Visit the [Dynamsoft Capture Vision Bundle](https://pypi.org/project/dynamsoft-capture-vision-bundle/) page on PyPI for more details.
55
6-
## About Dynamsoft Python Barcode SDK
6+
## About Dynamsoft Capture Vision Bundle
77
- Get a [30-day FREE trial license](https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform) to activate the SDK.
8-
- Install the official Python barcode SDK via `pip install dbr`.
8+
- Install the SDK via `pip install dynamsoft-capture-vision-bundle`.
99

1010
### Comparison Table
1111
| Feature | Unofficial Wrapper (Community) | Official Dynamsoft Python Barcode SDK |
1212
| --- | --- | --- |
1313
| Support | Community-driven, best effort | Official support from Dynamsoft |
14-
| Documentation | README only | [Comprehensive Online Documentation](https://www.dynamsoft.com/barcode-reader/programming/python/index.html) |
14+
| Documentation | README only | [Comprehensive Online Documentation](https://www.dynamsoft.com/capture-vision/docs/server/programming/python/?lang=python) |
1515
| API Coverage | Limited | Full API coverage |
1616
|Feature Updates| May lag behind the official SDK | First to receive new features |
1717
| Compatibility | Limited testing across environments| Thoroughly tested across all supported environments|
18+
| OS Support | Windows, Linux, macOS | Windows, Linux, macOS |
1819

1920
## Supported Python Edition
2021
* Python 3.x

examples/ctypes/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ This project explores an alternative approach to invoking C APIs from shared lib
2929
cmake --build .
3030
```
3131

32-
2. Get a valid license key from [Dynamsoft](https://www.dynamsoft.com/customer/license/trialLicense?product=dbr). Then, update the license key in the `success.py` file.
32+
2. Get a valid license key from [Dynamsoft](https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform). Then, update the license key in the `success.py` file.
3333

3434
```python
3535
license_key = b"LICENSE-KEY"

examples/ctypes/failure.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class TextResultArray(Structure):
109109
license_key = b"DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="
110110
error_msg_buffer = create_string_buffer(256)
111111
error_msg_buffer_len = len(error_msg_buffer)
112-
# https://www.dynamsoft.com/customer/license/trialLicense?product=dbr
112+
# https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform
113113
ret = DBR_InitLicense(license_key, error_msg_buffer, error_msg_buffer_len)
114114
print('initLicense: {}'.format(ret))
115115

examples/ctypes/success.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class ResultList(Structure):
3838
license_key = b"DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="
3939
error_msg_buffer = create_string_buffer(256)
4040
error_msg_buffer_len = len(error_msg_buffer)
41-
# https://www.dynamsoft.com/customer/license/trialLicense?product=dbr
41+
# https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform
4242
ret = DBR_InitLicense(license_key, error_msg_buffer, error_msg_buffer_len)
4343

4444
# DBR_CreateInstance

examples/official/10.x/file.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import sys
2+
from dynamsoft_capture_vision_bundle import *
3+
import os
4+
import cv2
5+
import numpy as np
6+
from utils import *
7+
8+
if __name__ == '__main__':
9+
10+
print("**********************************************************")
11+
print("Welcome to Dynamsoft Capture Vision - Barcode Sample")
12+
print("**********************************************************")
13+
14+
error_code, error_message = LicenseManager.init_license(
15+
"DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==")
16+
if error_code != EnumErrorCode.EC_OK and error_code != EnumErrorCode.EC_LICENSE_CACHE_USED:
17+
print("License initialization failed: ErrorCode:",
18+
error_code, ", ErrorString:", error_message)
19+
else:
20+
cvr_instance = CaptureVisionRouter()
21+
while (True):
22+
image_path = input(
23+
">> Input your image full path:\n"
24+
">> 'Enter' for sample image or 'Q'/'q' to quit\n"
25+
).strip('\'"')
26+
27+
if image_path.lower() == "q":
28+
sys.exit(0)
29+
30+
if image_path == "":
31+
image_path = "../../../images/multi.png"
32+
33+
if not os.path.exists(image_path):
34+
print("The image path does not exist.")
35+
continue
36+
result = cvr_instance.capture(
37+
image_path, EnumPresetTemplate.PT_READ_BARCODES.value)
38+
if result.get_error_code() != EnumErrorCode.EC_OK:
39+
print("Error:", result.get_error_code(),
40+
result.get_error_string())
41+
else:
42+
cv_image = cv2.imread(image_path)
43+
44+
items = result.get_items()
45+
print('Found {} barcodes.'.format(len(items)))
46+
for item in items:
47+
format_type = item.get_format()
48+
text = item.get_text()
49+
print("Barcode Format:", format_type)
50+
print("Barcode Text:", text)
51+
52+
location = item.get_location()
53+
x1 = location.points[0].x
54+
y1 = location.points[0].y
55+
x2 = location.points[1].x
56+
y2 = location.points[1].y
57+
x3 = location.points[2].x
58+
y3 = location.points[2].y
59+
x4 = location.points[3].x
60+
y4 = location.points[3].y
61+
del location
62+
63+
cv2.drawContours(
64+
cv_image, [np.intp([(x1, y1), (x2, y2), (x3, y3), (x4, y4)])], 0, (0, 255, 0), 2)
65+
66+
cv2.putText(cv_image, text, (x1, y1 - 10),
67+
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
68+
69+
cv2.imshow(
70+
"Original Image with Detected Barcodes", cv_image)
71+
cv2.waitKey(0)
72+
cv2.destroyAllWindows()
73+
74+
input("Press Enter to quit...")
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dynamsoft-capture-vision-bundle
2+
opencv-python

examples/official/10.x/utils.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
from dynamsoft_capture_vision_bundle import *
2+
import numpy as np
3+
4+
5+
def convertImageData2Mat(normalized_image):
6+
ba = bytearray(normalized_image.get_bytes())
7+
width = normalized_image.get_width()
8+
height = normalized_image.get_height()
9+
10+
channels = 3
11+
if normalized_image.get_image_pixel_format() == EnumImagePixelFormat.IPF_BINARY:
12+
channels = 1
13+
all = []
14+
skip = normalized_image.stride * 8 - width
15+
16+
index = 0
17+
n = 1
18+
for byte in ba:
19+
20+
byteCount = 7
21+
while byteCount >= 0:
22+
b = (byte & (1 << byteCount)) >> byteCount
23+
24+
if index < normalized_image.stride * 8 * n - skip:
25+
if b == 1:
26+
all.append(255)
27+
else:
28+
all.append(0)
29+
30+
byteCount -= 1
31+
index += 1
32+
33+
if index == normalized_image.stride * 8 * n:
34+
n += 1
35+
36+
mat = np.array(all, dtype=np.uint8).reshape(height, width, channels)
37+
return mat
38+
39+
elif normalized_image.get_image_pixel_format() == EnumImagePixelFormat.IPF_GRAYSCALED:
40+
channels = 1
41+
42+
mat = np.array(ba, dtype=np.uint8).reshape(height, width, channels)
43+
44+
return mat
45+
46+
47+
def convertMat2ImageData(mat):
48+
if len(mat.shape) == 3:
49+
height, width, channels = mat.shape
50+
pixel_format = EnumImagePixelFormat.IPF_RGB_888
51+
else:
52+
height, width = mat.shape
53+
channels = 1
54+
pixel_format = EnumImagePixelFormat.IPF_GRAYSCALED
55+
56+
stride = width * channels
57+
imagedata = ImageData(mat.tobytes(), width, height, stride, pixel_format)
58+
return imagedata
59+
60+
61+
class MRZResult:
62+
def __init__(self, item: ParsedResultItem):
63+
self.doc_type = item.get_code_type()
64+
self.raw_text = []
65+
self.doc_id = None
66+
self.surname = None
67+
self.given_name = None
68+
self.nationality = None
69+
self.issuer = None
70+
self.gender = None
71+
self.date_of_birth = None
72+
self.date_of_expiry = None
73+
if self.doc_type == "MRTD_TD3_PASSPORT":
74+
if item.get_field_value("passportNumber") != None and item.get_field_validation_status("passportNumber") != EnumValidationStatus.VS_FAILED:
75+
self.doc_id = item.get_field_value("passportNumber")
76+
elif item.get_field_value("documentNumber") != None and item.get_field_validation_status("documentNumber") != EnumValidationStatus.VS_FAILED:
77+
self.doc_id = item.get_field_value("documentNumber")
78+
79+
line = item.get_field_value("line1")
80+
if line is not None:
81+
if item.get_field_validation_status("line1") == EnumValidationStatus.VS_FAILED:
82+
line += ", Validation Failed"
83+
self.raw_text.append(line)
84+
line = item.get_field_value("line2")
85+
if line is not None:
86+
if item.get_field_validation_status("line2") == EnumValidationStatus.VS_FAILED:
87+
line += ", Validation Failed"
88+
self.raw_text.append(line)
89+
line = item.get_field_value("line3")
90+
if line is not None:
91+
if item.get_field_validation_status("line3") == EnumValidationStatus.VS_FAILED:
92+
line += ", Validation Failed"
93+
self.raw_text.append(line)
94+
95+
if item.get_field_value("nationality") != None and item.get_field_validation_status("nationality") != EnumValidationStatus.VS_FAILED:
96+
self.nationality = item.get_field_value("nationality")
97+
if item.get_field_value("issuingState") != None and item.get_field_validation_status("issuingState") != EnumValidationStatus.VS_FAILED:
98+
self.issuer = item.get_field_value("issuingState")
99+
if item.get_field_value("dateOfBirth") != None and item.get_field_validation_status("dateOfBirth") != EnumValidationStatus.VS_FAILED:
100+
self.date_of_birth = item.get_field_value("dateOfBirth")
101+
if item.get_field_value("dateOfExpiry") != None and item.get_field_validation_status("dateOfExpiry") != EnumValidationStatus.VS_FAILED:
102+
self.date_of_expiry = item.get_field_value("dateOfExpiry")
103+
if item.get_field_value("sex") != None and item.get_field_validation_status("sex") != EnumValidationStatus.VS_FAILED:
104+
self.gender = item.get_field_value("sex")
105+
if item.get_field_value("primaryIdentifier") != None and item.get_field_validation_status("primaryIdentifier") != EnumValidationStatus.VS_FAILED:
106+
self.surname = item.get_field_value("primaryIdentifier")
107+
if item.get_field_value("secondaryIdentifier") != None and item.get_field_validation_status("secondaryIdentifier") != EnumValidationStatus.VS_FAILED:
108+
self.given_name = item.get_field_value("secondaryIdentifier")
109+
110+
def to_string(self):
111+
msg = (f"Raw Text:\n")
112+
for index, line in enumerate(self.raw_text):
113+
msg += (f"\tLine {index + 1}: {line}\n")
114+
msg += (f"Parsed Information:\n"
115+
f"\tDocumentType: {self.doc_type or ''}\n"
116+
f"\tDocumentID: {self.doc_id or ''}\n"
117+
f"\tSurname: {self.surname or ''}\n"
118+
f"\tGivenName: {self.given_name or ''}\n"
119+
f"\tNationality: {self.nationality or ''}\n"
120+
f"\tIssuingCountryorOrganization: {self.issuer or ''}\n"
121+
f"\tGender: {self.gender or ''}\n"
122+
f"\tDateofBirth(YYMMDD): {self.date_of_birth or ''}\n"
123+
f"\tExpirationDate(YYMMDD): {self.date_of_expiry or ''}\n")
124+
return msg
125+
126+
127+
def print_results(result: ParsedResult) -> None:
128+
tag = result.get_original_image_tag()
129+
if isinstance(tag, FileImageTag):
130+
print("File:", tag.get_file_path())
131+
if result.get_error_code() != EnumErrorCode.EC_OK:
132+
print("Error:", result.get_error_string())
133+
else:
134+
items = result.get_items()
135+
print("Parsed", len(items), "MRZ Zones.")
136+
for item in items:
137+
mrz_result = MRZResult(item)
138+
print(mrz_result.to_string())

examples/official/9.x/django/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ This sample demonstrates how to create an online Barcode and QR Code Reader usin
2020

2121
- **SDK License**
2222

23-
To use the Dynamsoft Barcode Reader SDK, request a [30-day free trial license](https://www.dynamsoft.com/customer/license/trialLicense/?product=dbr).
23+
To use the Dynamsoft Barcode Reader SDK, request a [30-day free trial license](https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform).
2424

2525
## Usage
2626
1. Set the license key in `scanbarcode/views.py`:

examples/official/9.x/django/scanbarcode/views.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,21 @@
88
from dbr import *
99
import json
1010

11-
# Apply for a trial license: https://www.dynamsoft.com/customer/license/trialLicense?product=dbr
12-
BarcodeReader.init_license("DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==")
11+
# Apply for a trial license: https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform
12+
BarcodeReader.init_license(
13+
"DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==")
1314
reader = BarcodeReader()
1415

16+
1517
def index(request):
16-
return render(request, 'scanbarcode/index.html')
18+
return render(request, 'scanbarcode/index.html')
19+
1720

1821
def upload(request):
1922
out = "No barcode found"
2023
if request.method == 'POST':
21-
filePath = handle_uploaded_file(request.FILES['RemoteFile'], str(request.FILES['RemoteFile']))
24+
filePath = handle_uploaded_file(
25+
request.FILES['RemoteFile'], str(request.FILES['RemoteFile']))
2226
try:
2327
text_results = reader.decode_file(filePath)
2428
if text_results != None:
@@ -31,7 +35,6 @@ def upload(request):
3135
print(bre)
3236
return HttpResponse(out)
3337

34-
3538
return HttpResponse(out)
3639
# image = Image()
3740
# image.name = request.FILES['RemoteFile'].name
@@ -41,6 +44,7 @@ def upload(request):
4144

4245
return HttpResponse(out)
4346

47+
4448
def handle_uploaded_file(file, filename):
4549
if not os.path.exists('upload/'):
4650
os.mkdir('upload/')

0 commit comments

Comments
 (0)