Skip to content

Commit fff45c7

Browse files
committed
Update
1 parent 5094eb2 commit fff45c7

2 files changed

Lines changed: 68 additions & 38 deletions

File tree

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Python 1D/2D Barcode SDK
2-
A Python wrapper for the [Dynamsoft Barcode Reader SDK](https://www.dynamsoft.com/barcode-reader/overview/), providing user-friendly APIs across **Windows**, **Linux**, and **macOS**. Compatible with desktop PCs, embedded devices, **Raspberry Pi**, and **Jetson Nano**.
2+
A Python wrapper for the [Dynamsoft Barcode Reader SDK](https://www.dynamsoft.com/barcode-reader/overview/), providing simple and user-friendly APIs across **Windows**, **Linux**, and **macOS**. Compatible with desktop PCs, embedded devices, **Raspberry Pi**, and **Jetson Nano**.
33

44
> **Note**: This is an unofficial, community-maintained wrapper. For official support and full feature coverage, consider the [Dynamsoft Capture Vision Bundle](https://pypi.org/project/dynamsoft-capture-vision-bundle/) on PyPI.
55
@@ -14,10 +14,11 @@ A Python wrapper for the [Dynamsoft Barcode Reader SDK](https://www.dynamsoft.co
1414
| Feature | Community Wrapper | Official Dynamsoft SDK |
1515
|---------|------------------|------------------------|
1616
| **Support** | Community-driven | ✅ Official Dynamsoft support |
17-
| **Documentation** | Basic README | ✅ Comprehensive online docs |
18-
| **API Coverage** | Essential features | ✅ Complete API access |
19-
| **Updates** | May lag behind | ✅ Latest features first |
20-
| **Testing** | Limited environments | ✅ Thoroughly tested |
17+
| **Documentation** | Basic README and limited examples | ✅ Comprehensive online documentation |
18+
| **API Coverage** | Core features only | ✅ Full API coverage |
19+
| **Updates** | May lag behind | ✅ Always includes the latest features |
20+
| **Testing** | Tested in limited environments | ✅ Thoroughly tested |
21+
| **API Usage** | ✅ Simple and intuitive | More complex and verbose|
2122

2223
## 🔧 Installation
2324

barcodeQrSDK/__init__.py

Lines changed: 62 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
BarcodeReaderModule
3636
)
3737
import time
38+
from typing import List, Tuple, Callable, Union, Optional, Any
39+
import numpy as np
3840

3941
__version__ = BarcodeReaderModule.get_version()
4042

@@ -55,7 +57,7 @@ def has_next_image_to_fetch(self) -> bool:
5557
"""
5658
return True
5759

58-
def add_frame(self, imageData):
60+
def add_frame(self, imageData: ImageData) -> None:
5961
"""
6062
Adds a new image frame to the processing buffer.
6163
@@ -74,7 +76,7 @@ class MyCapturedResultReceiver(CapturedResultReceiver):
7476
to BarcodeResult objects before passing to the user-defined listener.
7577
"""
7678

77-
def __init__(self, listener):
79+
def __init__(self, listener: Callable[[List['BarcodeResult']], None]) -> None:
7880
"""
7981
Initialize the result receiver with a callback listener.
8082
@@ -86,7 +88,7 @@ def __init__(self, listener):
8688
super().__init__()
8789
self.listener = listener
8890

89-
def on_captured_result_received(self, result):
91+
def on_captured_result_received(self, result: Any) -> None:
9092
"""
9193
Called when barcode detection results are received.
9294
@@ -97,7 +99,7 @@ def on_captured_result_received(self, result):
9799
result: The captured result from the SDK containing detected items.
98100
"""
99101
items = result.get_items()
100-
output = []
102+
output: List['BarcodeResult'] = []
101103
for item in items:
102104
barcode = BarcodeResult(item)
103105
output.append(barcode)
@@ -118,15 +120,15 @@ class BarcodeResult:
118120
location as four corner points
119121
"""
120122

121-
def __init__(self, item):
123+
def __init__(self, item: Any) -> None:
122124
"""
123125
Initialize a BarcodeResult from an SDK barcode item.
124126
125127
Args:
126128
item: The barcode item from the SDK containing detection results.
127129
"""
128-
self.text = item.get_text()
129-
self.format = item.get_format_string()
130+
self.text: str = item.get_text()
131+
self.format: str = item.get_format_string()
130132

131133
# Extract location coordinates (four corner points)
132134
location = item.get_location()
@@ -139,14 +141,14 @@ def __init__(self, item):
139141
x4 = location.points[3].x
140142
y4 = location.points[3].y
141143

142-
self.x1 = x1
143-
self.y1 = y1
144-
self.x2 = x2
145-
self.y2 = y2
146-
self.x3 = x3
147-
self.y3 = y3
148-
self.x4 = x4
149-
self.y4 = y4
144+
self.x1: float = x1
145+
self.y1: float = y1
146+
self.x2: float = x2
147+
self.y2: float = y2
148+
self.x3: float = x3
149+
self.y3: float = y3
150+
self.x4: float = x4
151+
self.y4: float = y4
150152

151153
class BarcodeReader:
152154
"""
@@ -163,7 +165,7 @@ class BarcodeReader:
163165
print(f"Found: {barcode.text} ({barcode.format})")
164166
"""
165167

166-
def __init__(self):
168+
def __init__(self) -> None:
167169
"""
168170
Initialize the barcode reader with default settings.
169171
@@ -173,12 +175,12 @@ def __init__(self):
173175
cvr_instance = CaptureVisionRouter()
174176
error_code, settings, error_message = cvr_instance.output_settings(EnumPresetTemplate.PT_READ_BARCODES.value)
175177
cvr_instance.init_settings(settings)
176-
self.fetcher = FrameFetcher()
178+
self.fetcher: FrameFetcher = FrameFetcher()
177179
cvr_instance.set_input(self.fetcher)
178-
self.cvr_instance = cvr_instance
179-
self.receiver = None
180+
self.cvr_instance: CaptureVisionRouter = cvr_instance
181+
self.receiver: Optional[MyCapturedResultReceiver] = None
180182

181-
def getParameters(self):
183+
def getParameters(self) -> str:
182184
"""
183185
Get the current detection parameters/settings.
184186
@@ -189,7 +191,7 @@ def getParameters(self):
189191
error_code, settings, error_message = self.cvr_instance.output_settings(EnumPresetTemplate.PT_READ_BARCODES.value)
190192
return settings
191193

192-
def setParameters(self, params):
194+
def setParameters(self, params: str) -> Tuple[int, str]:
193195
"""
194196
Set custom detection parameters/settings.
195197
@@ -203,7 +205,7 @@ def setParameters(self, params):
203205
error_code, error_message = self.cvr_instance.init_settings(params)
204206
return error_code, error_message
205207

206-
def addAsyncListener(self, listener):
208+
def addAsyncListener(self, listener: Callable[[List[BarcodeResult]], None]) -> None:
207209
"""
208210
Start asynchronous barcode detection with a callback listener.
209211
@@ -226,7 +228,7 @@ def on_barcode_detected(barcodes):
226228
self.cvr_instance.add_result_receiver(self.receiver)
227229
error_code, error_message = self.cvr_instance.start_capturing('')
228230

229-
def clearAsyncListener(self):
231+
def clearAsyncListener(self) -> None:
230232
"""
231233
Stop asynchronous barcode detection and remove the listener.
232234
@@ -238,7 +240,7 @@ def clearAsyncListener(self):
238240
self.receiver = None
239241
self.cvr_instance.stop_capturing()
240242

241-
def decode(self, input):
243+
def decode(self, input: Union[str, ImageData]) -> List[BarcodeResult]:
242244
"""
243245
Core decode method that handles various input types.
244246
@@ -252,7 +254,7 @@ def decode(self, input):
252254
"""
253255
result = self.cvr_instance.capture(input, '')
254256

255-
output = []
257+
output: List[BarcodeResult] = []
256258

257259
if result.get_error_code() != EnumErrorCode.EC_OK:
258260
print("Error:", result.get_error_code(),
@@ -265,7 +267,7 @@ def decode(self, input):
265267

266268
return output
267269

268-
def decodeFile(self, file_path: str):
270+
def decodeFile(self, file_path: str) -> List[BarcodeResult]:
269271
"""
270272
Decode barcodes from an image file.
271273
@@ -283,7 +285,7 @@ def decodeFile(self, file_path: str):
283285
"""
284286
return self.decode(file_path)
285287

286-
def decodeMat(self, mat):
288+
def decodeMat(self, mat: np.ndarray) -> List[BarcodeResult]:
287289
"""
288290
Decode barcodes from an OpenCV image matrix.
289291
@@ -301,7 +303,7 @@ def decodeMat(self, mat):
301303
"""
302304
return self.decode(convertMat2ImageData(mat))
303305

304-
def decodeBytes(self, bytes, width, height, stride, pixel_format):
306+
def decodeBytes(self, bytes: bytes, width: int, height: int, stride: int, pixel_format: EnumImagePixelFormat) -> List[BarcodeResult]:
305307
"""
306308
Decode barcodes from raw image bytes.
307309
@@ -325,7 +327,7 @@ def decodeBytes(self, bytes, width, height, stride, pixel_format):
325327
imagedata = ImageData(bytes, width, height, stride, pixel_format)
326328
return self.decode(imagedata)
327329

328-
def decodeMatAsync(self, mat):
330+
def decodeMatAsync(self, mat: np.ndarray) -> None:
329331
"""
330332
Add an OpenCV matrix to the async processing queue.
331333
@@ -343,7 +345,7 @@ def decodeMatAsync(self, mat):
343345
"""
344346
self.fetcher.add_frame(convertMat2ImageData(mat))
345347

346-
def decodeBytesAsync(self, bytes, width, height, stride, pixel_format):
348+
def decodeBytesAsync(self, bytes: bytes, width: int, height: int, stride: int, pixel_format: EnumImagePixelFormat) -> None:
347349
"""
348350
Add raw image bytes to the async processing queue.
349351
@@ -361,7 +363,7 @@ def decodeBytesAsync(self, bytes, width, height, stride, pixel_format):
361363
self.fetcher.add_frame(imagedata)
362364

363365

364-
def initLicense(licenseKey: str):
366+
def initLicense(licenseKey: str) -> Tuple[int, str]:
365367
"""
366368
Initialize the Dynamsoft license for barcode detection.
367369
@@ -382,7 +384,7 @@ def initLicense(licenseKey: str):
382384
errorCode, errorMsg = LicenseManager.init_license(licenseKey)
383385
return errorCode, errorMsg
384386

385-
def createInstance():
387+
def createInstance() -> BarcodeReader:
386388
"""
387389
Create a new BarcodeReader instance.
388390
@@ -399,7 +401,7 @@ def createInstance():
399401
"""
400402
return BarcodeReader()
401403

402-
def convertMat2ImageData(mat):
404+
def convertMat2ImageData(mat: np.ndarray) -> ImageData:
403405
"""
404406
Convert an OpenCV matrix to Dynamsoft ImageData format.
405407
@@ -429,3 +431,30 @@ def convertMat2ImageData(mat):
429431
stride = width * channels
430432
imagedata = ImageData(mat.tobytes(), width, height, stride, pixel_format)
431433
return imagedata
434+
435+
def wrapImageData(width: int, height: int, stride: int, pixel_format: EnumImagePixelFormat, bytes: bytes) -> ImageData:
436+
"""
437+
Create an ImageData object from raw image parameters.
438+
439+
This utility function creates a properly formatted ImageData object
440+
from raw image specifications and byte data.
441+
442+
Args:
443+
width (int): Image width in pixels
444+
height (int): Image height in pixels
445+
stride (int): Number of bytes per image row
446+
pixel_format: EnumImagePixelFormat specifying the pixel layout
447+
bytes: Raw image data as bytes
448+
449+
Returns:
450+
ImageData: Formatted image data ready for SDK processing.
451+
452+
Example:
453+
image_data = wrapImageData(
454+
640, 480, 1920,
455+
EnumImagePixelFormat.IPF_RGB_888,
456+
raw_bytes
457+
)
458+
"""
459+
imagedata = ImageData(bytes, width, height, stride, pixel_format)
460+
return imagedata

0 commit comments

Comments
 (0)