Skip to content

Commit

Permalink
Merge pull request #28 from NaturalHistoryMuseum/feature/27-pyzbar
Browse files Browse the repository at this point in the history
Feature/27 pyzbar
  • Loading branch information
quicklizard99 authored Nov 9, 2016
2 parents 2d7cba8 + a5f47bb commit ce89093
Show file tree
Hide file tree
Showing 13 changed files with 52 additions and 50 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ virtualenv:

install:
- sudo apt-get -qq update
- sudo apt-get install -y --fix-missing libdmtx0a python-opencv
- pip install -r requirements.txt
- sudo apt-get install -y --fix-missing libdmtx0a libzbar0 python-opencv
- pip install -r requirements.pip

script:
- nosetests
- python -m nose --verbose --with-coverage --cover-inclusive --cover-tests --cover-package=gouda gouda

after_success:
- coveralls
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# v0.1.9
- #27 Support pyzbar

# v0.1.8
- #24 Support pylibdmtx

Expand Down
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
include *.py
include requirements.txt
include requirements.pip
include gouda/tests/test_data/*png
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ The easiest way is to install the current Python 2.7 release of
conda update --all
pip install --upgrade pip
python <Anaconda dir>\Scripts\pywin32_postinstall.py -install
pip install -r requirements.txt
pip install -r requirements.pip

## Install [OpenCV](http://www.opencv.org/)
### Linux
Expand Down Expand Up @@ -98,7 +98,7 @@ Windows only. Download and install their [SDK](http://www.inliteresearch.com/).
### libdmtx

The [pylibdmtx](https://pypi.python.org/pypi/pylibdmtx/) Python package is
a dependency of `gouda` and is listed in `requirements.txt`.
a dependency of `gouda` and is listed in `requirements.pip`.

The `libdmtx` `DLL`s are included with the Windows Python wheel builds
of `pylibdmtx`.
Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ echo Tests
nosetests --with-coverage --cover-html --cover-inclusive --cover-erase --cover-tests --cover-package=gouda

echo Build
./setup.py sdist
./setup.py bdist_wheel
pyinstaller --onefile --clean decode_barcodes.spec
26 changes: 12 additions & 14 deletions decode_barcodes.spec
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# For PyInstaller build on Mac
# For PyInstaller build

import sys

from pathlib import Path

from pylibdmtx import pylibdmtx
from pyzbar import pyzbar


block_cipher = None

a = Analysis(['gouda/scripts/decode_barcodes.py'],
Expand All @@ -18,13 +22,14 @@ a = Analysis(['gouda/scripts/decode_barcodes.py'],
win_private_assemblies=False,
cipher=block_cipher)

if 'darwin' == sys.platform:
# libdmtx dylib is not detected because it is loaded by a ctypes call in
# pylibdmtx
a.binaries += TOC([
('libdmtx.dylib', '/usr/local/Cellar/libdmtx/0.7.4/lib/libdmtx.dylib', 'BINARY'),
])

# dylibs not detected because they are loaded by ctypes
a.binaries += TOC([
(Path(dep._name).name, dep._name, 'BINARY')
for dep in pylibdmtx.EXTERNAL_DEPENDENCIES + pyzbar.EXTERNAL_DEPENDENCIES
])

if 'darwin' == sys.platform:
# PyInstaller does not detect some dylibs, in some cases (I think) because they
# are symlinked.
# See Stack Overflow post http://stackoverflow.com/a/17595149 for example
Expand Down Expand Up @@ -56,13 +61,6 @@ if 'darwin' == sys.platform:
a.binaries += TOC([
(lib, str(LIB.joinpath(lib).resolve()), 'BINARY') for lib in MISSING_DYLIBS
])
elif 'win32' == sys.platform:
# libdmtx dylib is not detected because it is loaded by a ctypes call in
# pylibdmtx
fname = 'libdmtx-{0}.dll'.format('64' if sys.maxsize > 2**32 else '32')
a.binaries += TOC([
(fname, str(Path(sys.argv[0]).parent.parent.joinpath(fname)), 'BINARY'),
])


pyz = PYZ(a.pure, a.zipped_data,
Expand Down
2 changes: 1 addition & 1 deletion gouda/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.1.8'
__version__ = '0.1.9'
27 changes: 9 additions & 18 deletions gouda/engines/zbar_engine.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,34 @@
# This file is not called zbar.py to avoid collision with the zbar package

import cv2

from gouda.barcode import Barcode
from gouda.gouda_error import GoudaError
from gouda.util import debug_print

from PIL import Image

try:
import zbar
from pyzbar import pyzbar
except ImportError:
zbar = None
pyzbar = None


class ZbarEngine(object):
"""Decode using the zbar library
http://sourceforge.net/projects/zbar/
https://pypi.python.org/pypi/zbar
https://pypi.python.org/pypi/pyzbar
"""
def __init__(self):
if not self.available():
raise GoudaError('zbar unavailable')

@classmethod
def available(cls):
return zbar is not None
return pyzbar is not None

def decode_file(self, path):
return self(cv2.imread(str(path), cv2.IMREAD_GRAYSCALE))
return self(Image.open(str(path)))

def __call__(self, img):
# Decode barcodes in img using zbar
# https://github.com/ZBar/ZBar/blob/master/python/README
# https://github.com/herbyme/zbar/blob/master/python/examples/scan_image.py
scanner = zbar.ImageScanner()
height, width = img.shape[:2]
if 'uint8' != img.dtype or 2 != len(img.shape):
debug_print('Convert to greyscale for zbar')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
image = zbar.Image(width, height, 'Y800', img.tostring())
scanner.scan(image)
return [Barcode(str(s.type), unicode(s.data, 'utf8')) for s in image]
# Decode barcodes in img using pyzbar
return [Barcode(r.type, r.data) for r in pyzbar.decode(img)]
2 changes: 1 addition & 1 deletion gouda/scripts/decode_barcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
def decode(paths, strategies, engine, visitors, read_greyscale):
"""Finds and decodes barcodes in images given in pathss
"""
for p in paths:
for p in sorted(paths):
if p.is_dir():
# Descend into directory
decode(p.iterdir(), strategies, engine, visitors, read_greyscale)
Expand Down
6 changes: 4 additions & 2 deletions gouda/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ def debug_print(*args, **kwargs):


def read_image(path, greyscale):
flags = cv2.IMREAD_GRAYSCALE if greyscale else cv2.IMREAD_UNCHANGED
return cv2.imread(str(path), flags)
if greyscale:
return cv2.imread(str(path), cv2.IMREAD_GRAYSCALE)
else:
return cv2.imread(str(path))


def expand_wildcard(args):
Expand Down
13 changes: 13 additions & 0 deletions requirements.pip
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# TODO How to specify OpenCV? 'cv2>=2.4.8',
pathlib>=1.0.1
Pillow>=3.2.0
pylibdmtx==0.1.4
pyzbar==0.1.2
numpy>=1.8.2

# Packages required for testing
coveralls>=1.1
nose>=1.3.4

# Packages required for distribution
PyInstaller==3.1.1
7 changes: 0 additions & 7 deletions requirements.txt

This file was deleted.

1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
# TODO How to specify OpenCV? 'cv2>=2.4.8,<3',
'pathlib>=1.0.1',
'pylibdmtx>=0.1.1',
'pyzbar>=0.1.1',
'numpy>=1.8.2',
],
'tests_require': [
Expand Down

0 comments on commit ce89093

Please sign in to comment.