Skip to content

Commit

Permalink
pyzbar support decoding binary QR code
Browse files Browse the repository at this point in the history
libzbar support raw binary data since 0.23.1. See more: mchehab/zbar@59e0ed1

Refer to KlaasJelmer's modification to add configuration option ZBAR_CFG_BINARY to pyzbar. See more: NaturalHistoryMuseum#82
And modify the conversion method of symbol data to support binary data.
  • Loading branch information
oufm committed Apr 18, 2021
1 parent 833b375 commit bfc032a
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 7 deletions.
14 changes: 10 additions & 4 deletions pyzbar/pyzbar.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from collections import namedtuple
from contextlib import contextmanager
from ctypes import cast, c_void_p, string_at
from ctypes import cast, c_void_p

from .locations import bounding_box, convex_hull, Point, Rect
from .pyzbar_error import PyZbarError
Expand All @@ -9,7 +9,7 @@
zbar_image_scanner_create, zbar_image_scanner_destroy,
zbar_image_create, zbar_image_destroy, zbar_image_set_format,
zbar_image_set_size, zbar_image_set_data, zbar_scan_image,
zbar_image_first_symbol, zbar_symbol_get_data,
zbar_image_first_symbol, zbar_symbol_get_data, zbar_symbol_get_data_length,
zbar_symbol_get_loc_size, zbar_symbol_get_loc_x, zbar_symbol_get_loc_y,
zbar_symbol_next, ZBarConfig, ZBarSymbol, EXTERNAL_DEPENDENCIES
)
Expand Down Expand Up @@ -97,7 +97,8 @@ def _decode_symbols(symbols):
Decoded: decoded symbol
"""
for symbol in symbols:
data = string_at(zbar_symbol_get_data(symbol))
data = zbar_symbol_get_data(symbol)
data = data[:zbar_symbol_get_data_length(symbol)]
# The 'type' int in a value in the ZBarSymbol enumeration
symbol_type = ZBarSymbol(symbol.contents.type).name
polygon = convex_hull(
Expand Down Expand Up @@ -167,13 +168,14 @@ def _pixel_data(image):
return pixels, width, height


def decode(image, symbols=None):
def decode(image, symbols=None, binary=False):
"""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.
binary: bool If true, do not convert binary data to text.
Returns:
:obj:`list` of :obj:`Decoded`: The values decoded from barcodes.
Expand All @@ -197,6 +199,10 @@ def decode(image, symbols=None):
zbar_image_scanner_set_config(
scanner, symbol, ZBarConfig.CFG_ENABLE, 1
)

if binary:
zbar_image_scanner_set_config(scanner, 0, ZBarConfig.CFG_BINARY, 1)

with _image() as img:
zbar_image_set_format(img, _FOURCC['L800'])
zbar_image_set_size(img, width, height)
Expand Down
7 changes: 4 additions & 3 deletions pyzbar/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""
from ctypes import (
c_ubyte, c_char_p, c_int, c_uint, c_ulong, c_void_p, Structure,
CFUNCTYPE, POINTER
CFUNCTYPE, POINTER, c_char
)
from enum import IntEnum, unique

Expand Down Expand Up @@ -67,7 +67,8 @@ class ZBarConfig(IntEnum):
CFG_ADD_CHECK = 1 # /**< enable check digit when optional */
CFG_EMIT_CHECK = 2 # /**< return check digit when present */
CFG_ASCII = 3 # /**< enable full ASCII character set */
CFG_NUM = 4 # /**< number of boolean decoder configs */
CFG_BINARY = 4 # /**< don't convert binary data to text */
CFG_NUM = 5 # /**< number of boolean decoder configs */

CFG_MIN_LEN = 0x20 # /**< minimum data length for valid decode */
CFG_MAX_LEN = 0x21 # /**< maximum data length for valid decode */
Expand Down Expand Up @@ -234,7 +235,7 @@ def zbar_function(fname, restype, *args):

zbar_symbol_get_data = zbar_function(
'zbar_symbol_get_data',
c_char_p,
POINTER(c_char),
POINTER(zbar_symbol)
)

Expand Down

0 comments on commit bfc032a

Please sign in to comment.