Skip to content
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
56 changes: 55 additions & 1 deletion pyzbar/pyzbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@
zbar_symbol_get_loc_size, zbar_symbol_get_loc_x, zbar_symbol_get_loc_y,
zbar_symbol_get_quality, zbar_symbol_next, ZBarConfig, ZBarOrientation,
ZBarSymbol, EXTERNAL_DEPENDENCIES,
zbar_image_convert, zbar_image_convert_resize, zbar_image_get_data, zbar_image_get_data_length,
)

__all__ = [
'decode', 'Point', 'Rect', 'Decoded', 'ZBarSymbol', 'EXTERNAL_DEPENDENCIES', 'ORIENTATION_AVAILABLE'
]




ORIENTATION_AVAILABLE = zbar_symbol_get_orientation is not None

Decoded = namedtuple('Decoded', 'data type rect polygon quality orientation')
Expand Down Expand Up @@ -159,6 +162,9 @@ def _pixel_data(image):
if 3 == len(image.shape):
# Take just the first channel
image = image[:, :, 0]



if 'uint8' != str(image.dtype):
image = image.astype('uint8')
try:
Expand Down Expand Up @@ -204,8 +210,9 @@ def decode(image, symbols=None):
Returns:
:obj:`list` of :obj:`Decoded`: The values decoded from barcodes.
"""
pixels, width, height = _pixel_data(image)

pixels, width, height = _pixel_data(image)

results = []
with _image_scanner() as scanner:
if symbols:
Expand Down Expand Up @@ -234,3 +241,50 @@ def decode(image, symbols=None):
results.extend(_decode_symbols(_symbols_for_image(img)))

return results

######################EXTRA FUNCTIONALITY FOR PYZBAR################################################

from ctypes import c_ubyte
import numpy as np
from PIL import Image
def fourcc(a, b, c, d):
return (ord(a) | (ord(b) << 8) | (ord(c) << 16) | (ord(d) << 24))


def local_decode(image):

# ensure uint8, C-contiguous RGB

if image.dtype != np.uint8 or not image.flags['C_CONTIGUOUS']:
image = np.ascontiguousarray(image, dtype=np.uint8)
h, w = image.shape[:2]

results = []
with _image_scanner() as scanner:
with _image() as img:
zbar_image_set_format(img, fourcc('R','G','B','3'))
zbar_image_set_size(img, w, h)
# pass pointer + byte length (no-op cleanup is fine as None)
zbar_image_set_data(img, c_void_p(image.ctypes.data), image.nbytes, None)

dst = zbar_image_convert(img, fourcc('Y','8','0','0'))

# after you have `dst` (Y800) from zbar_image_convert and know w,h:
datalen = zbar_image_get_data_length(dst)
ptr = zbar_image_get_data(dst)
buf = (c_ubyte * datalen).from_address(ptr)
gray = np.frombuffer(buf, dtype=np.uint8).reshape(h, w) # h,w from original image

# Image.fromarray(gray, mode='L').save("converted_y800.png")
try:
decoded = zbar_scan_image(scanner, dst)
if decoded < 0:
raise PyZbarError('Unsupported image format')
# read symbols from the image you scanned
results.extend(_decode_symbols(_symbols_for_image(dst)))
finally:
zbar_image_destroy(dst) # free converted Y800 buffer
return results


#########################################################################
42 changes: 40 additions & 2 deletions pyzbar/wrapper.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Low-level wrapper around zbar's interface
"""
from ctypes import (
c_ubyte, c_char_p, c_int, c_uint, c_ulong, c_void_p, Structure,
c_ubyte, c_char_p, c_int, c_uint, c_ulong, c_void_p, Structure, c_uint32,
CFUNCTYPE, POINTER
)
from enum import IntEnum, unique
Expand All @@ -18,7 +18,8 @@
'zbar_symbol_get_data_length', 'zbar_symbol_get_data',
'zbar_symbol_get_loc_size', 'zbar_symbol_get_loc_x',
'zbar_symbol_get_loc_y', 'zbar_symbol_next',
'zbar_symbol_get_orientation', 'zbar_symbol_get_quality',
'zbar_symbol_get_orientation', 'zbar_symbol_get_quality',
'zbar_image_convert', 'zbar_image_convert_resize', 'zbar_image_get_data', 'zbar_image_get_data_length',
]

# Globals populated in load_libzbar
Expand Down Expand Up @@ -92,6 +93,12 @@ class ZBarOrientation(IntEnum):
LEFT = 3 # /**< sideways, read bottom to top */








# Structs
class zbar_image_scanner(Structure):
"""Opaque C++ class with private implementation
Expand Down Expand Up @@ -148,6 +155,37 @@ def zbar_function(fname, restype, *args):
return prototype((fname, load_libzbar()))


############################INTRODUCING MORE WRAPPER##########################################
zbar_image_convert = zbar_function(
'zbar_image_convert',
POINTER(zbar_image), # returns zbar_image*
POINTER(zbar_image), # const zbar_image* src
c_uint32 # unsigned long dst fourcc (use c_uint32)
)

zbar_image_convert_resize = zbar_function(
'zbar_image_convert_resize',
POINTER(zbar_image), # returns zbar_image*
POINTER(zbar_image), # const zbar_image* src
c_uint32, # dst fourcc
c_uint, # width
c_uint # height
)

zbar_image_get_data = zbar_function(
'zbar_image_get_data',
c_void_p,
POINTER(zbar_image)
)

zbar_image_get_data_length = zbar_function(
'zbar_image_get_data_length',
c_ulong,
POINTER(zbar_image)
)

#############################################################################################

zbar_version = zbar_function(
'zbar_version',
c_int,
Expand Down