diff --git a/README.rst b/README.rst index 3c0c2e9..074cb1b 100644 --- a/README.rst +++ b/README.rst @@ -192,6 +192,30 @@ symbol types >>> decode(Image.open('pyzbar/tests/qrcode.png'), symbols=[ZBarSymbol.CODE128]) [] +To change any of the other ZBar default settings found in `pyzbar.wrapper.ZBarConfig +`__ just pass +a config object to the ``decode`` method + +:: + + >>> from pyzbar.pyzbar import ZBarSymbol + >>> from pyzbar.pyzbar import ZBarConfig + >>> # Build config object + >>> config = {} + >>> config[ZBarSymbol.I25] = {ZBarConfig.CFG_MIN_LEN: 2} # change min code length for I25 codes to 2 digits, ZBar defaults to 6 + >>> decode(Image.open('pyzbar/tests/short_codeI25.png'), config=config) + [ + Decoded( + data=b'75', + type='I25', + rect=Rect(left=1, top=0, width=52, height=56), + polygon=[ + Point(x=1, y=1), Point(x=1, y=55), Point(x=53, y=56), + Point(x=53, y=0) + ] + ) + ] + Bounding boxes and polygons --------------------------- diff --git a/pyzbar/pyzbar.py b/pyzbar/pyzbar.py index ae44367..d1eefd2 100644 --- a/pyzbar/pyzbar.py +++ b/pyzbar/pyzbar.py @@ -167,13 +167,15 @@ def _pixel_data(image): return pixels, width, height -def decode(image, symbols=None): +def decode(image, symbols=None, config=None): """Decodes datamatrix barcodes in `image`. Args: image: `numpy.ndarray`, `PIL.Image` or tuple (pixels, width, height) symbols: iter(ZBarSymbol) the symbol types to decode; if `None`, uses `zbar`'s default behaviour, which is to decode all symbol types. + config: dict(ZBarSymbol: dict(ZBarConfig: value)) per-symbol config + options to change default ZBar settings Returns: :obj:`list` of :obj:`Decoded`: The values decoded from barcodes. @@ -197,6 +199,15 @@ def decode(image, symbols=None): zbar_image_scanner_set_config( scanner, symbol, ZBarConfig.CFG_ENABLE, 1 ) + + # Set per-symbol config options for the scanner + if config: + for symbol, options in config.items(): + for option, value in options.items(): + zbar_image_scanner_set_config( + scanner, symbol, option, value + ) + with _image() as img: zbar_image_set_format(img, _FOURCC['L800']) zbar_image_set_size(img, width, height) diff --git a/pyzbar/tests/short_codeI25.png b/pyzbar/tests/short_codeI25.png new file mode 100644 index 0000000..1021e41 Binary files /dev/null and b/pyzbar/tests/short_codeI25.png differ diff --git a/pyzbar/tests/test_pyzbar.py b/pyzbar/tests/test_pyzbar.py index 683f7e0..e41c04e 100644 --- a/pyzbar/tests/test_pyzbar.py +++ b/pyzbar/tests/test_pyzbar.py @@ -19,7 +19,7 @@ cv2 = None from pyzbar.pyzbar import ( - decode, Decoded, Rect, ZBarSymbol, EXTERNAL_DEPENDENCIES + decode, Decoded, Rect, ZBarSymbol, ZBarConfig, EXTERNAL_DEPENDENCIES ) from pyzbar.pyzbar_error import PyZbarError @@ -66,11 +66,19 @@ class TestDecode(unittest.TestCase): polygon=[(32, 352), (177, 366), (190, 222), (46, 208)]) ] + EXPECTED_CODEI25 = [ + Decoded( + data=b'75', + type='I25', + rect=Rect(left=1, top=0, width=52, height=56), + polygon=[(1, 1), (1, 55), (53, 56), (53, 0)]) + ] + def setUp(self): - self.code128, self.qrcode, self.qrcode_rotated, self.empty = ( + self.code128, self.qrcode, self.qrcode_rotated, self.empty, self.codei25 = ( Image.open(str(TESTDATA.joinpath(fname))) for fname in - ('code128.png', 'qrcode.png', 'qrcode_rotated.png', 'empty.png') + ('code128.png', 'qrcode.png', 'qrcode_rotated.png', 'empty.png', 'short_codeI25.png') ) self.maxDiff = None @@ -93,6 +101,13 @@ def test_decode_qrcode_rotated(self): res = decode(self.qrcode_rotated) self.assertEqual(self.EXPECTED_QRCODE_ROTATED, res) + def test_config(self): + "Read a 2-digit I25 barcode (ZBar defaults to min 6 digits for I25)" + config = {} + config[ZBarSymbol.I25] = {ZBarConfig.CFG_MIN_LEN: 2} + res = decode(self.codei25, config=config) + self.assertEqual(self.EXPECTED_CODEI25, res) + def test_symbols(self): "Read only qrcodes in `qrcode.png`" res = decode(self.qrcode, symbols=[ZBarSymbol.QRCODE])