From 1bce3965ece5aaeab2afa42eab19aa58b1e847e8 Mon Sep 17 00:00:00 2001 From: Sam Lewis Date: Wed, 10 Apr 2019 09:14:01 -0400 Subject: [PATCH] changes related to config (see below lines): Changes: - added optional config parameter to pyzbar.pyzbar.decode - the structure is a nested dictionary where the keys are ZBarSymbol objects, and the values are dicts of ZBarConfig-value key-value pairs Explanation: I am submitting this PR to accomodate our use case of using I25 barcodes that are only 2 digits. ZBar defaults to a minimum length of 6 for I25 codes, and we had no way to change that in the current pyzbar. While I was in the code, I figured I would make it generic to allow changing any config option(s) for any symbol. The structure of the config object is admittedly a bit complicated. I decided to make it a nested dict for 2 reasons: 1. to allow changing barcode settings for each individual code rather than for all codes 2. to allow passing only the config object without passing the symbols object --- README.rst | 24 ++++++++++++++++++++++++ pyzbar/pyzbar.py | 13 ++++++++++++- pyzbar/tests/short_codeI25.png | Bin 0 -> 1367 bytes pyzbar/tests/test_pyzbar.py | 21 ++++++++++++++++++--- 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 pyzbar/tests/short_codeI25.png 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 0000000000000000000000000000000000000000..1021e415bde09c6236d79228edc50aec74662684 GIT binary patch literal 1367 zcmXYweQeKH6vj`fSeuBKO}C#6eZgv1B+C)68>$_ftVOfC(MZL{v6eA{m2GwxHPqfP zOHa`lHF_sP6`ibEvlr6#Y|PwXbQ!5l7mURe)17_0?f!Ff?@8`?&gXgVgr~<3A2D+% zOomqYZy^8yFn|Ck7yyG{2n>S}FbWpHB3J^;U&$jAcy3L9Fr4rN*>4~c_Po`g}hP#3P^z{Fa@EYq(F+KM9QQ>8X<^? zBLguogG5Bw02^dOY?zI(QMSMq*%Di3D{Pe=utRplj@b!2We@C;J+Wu@!d^K52joB; zn1gUoR$xU|Vr5ogjp#>aqW}r8fJA190Wm0s#IP6Z0}5QpMO9E%fi zDjvk6coNUzMZ8J?2`GUiumq8yq9BT*B+8;9s_j9D+=!4wx}stf1p{hO4XI%@qDIw% zT2xDFS*@s5b)XK_kvdi<>Qp_bNA;wh)r)%702)vOX|gW9j!{{-Bp5C>-tPfE^M8GnCjR_VTNb*nq~9sJ?&6BoW-)8(;|@>2H~ zj;-yHmVdr<;jGM(o>NM0KD41<=Bk0FyrQN@zsAkI=KNB8Huuu8(zF?c58OR4;Kb&P z*az06JHFI_(HX!h>GJ89?gP&jEzza?*9T3fy6+sghgE^2EyG$?O>R&Ci6 zcbB$I-L>fW{Orb?1^Gu_yHMD+?!kG}4;GyJ@zmUt*Jge*A(oc(`O^6pDyIL{$9rXrFEP?y|rrgo{EkulU_bjUHHSt&mYODop$ZY@qN>F9BnJZS!ZhtUhVzUtwVHi z*B5=p{C#fN#jj*z+OQR;mtARU{Pc8rpDnGoE;j9$p@)0tkNV@rR@}TGC%>ks>1u7` zoa0Sx%UgcFI_Bu_hwiPod8fWLe|}xdudz4csI~9weXIFKs+nSJ&*tv9Zhr)`{CGp)RX6EHC z-nl(1abkMLybjkN$@nODMQl#cPCuk-m