Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to configure ZBar options per symbol #58

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
<https://github.com/NaturalHistoryMuseum/pyzbar/blob/master/pyzbar/wrapper.py>`__ 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
---------------------------

Expand Down
13 changes: 12 additions & 1 deletion pyzbar/pyzbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)
Expand Down
Binary file added pyzbar/tests/short_codeI25.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 18 additions & 3 deletions pyzbar/tests/test_pyzbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand All @@ -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])
Expand Down