Skip to content

Commit

Permalink
Add helper to add background color on image
Browse files Browse the repository at this point in the history
For some images with alpha channel, the background color and the
foreground color are the same after grey scale conversion, this will no
allow us to detect 1D or 2D code on the image.

The copy_image_on_background() allow to add a background color on a
image to avoid this issue.
  • Loading branch information
Fabien Bochu committed Aug 22, 2017
1 parent 28ea46f commit 873dfaf
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 5 deletions.
3 changes: 2 additions & 1 deletion Changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ ChangeLog
2.0 (unreleased)
----------------

- Drop deprecated qr_code_scanner() method.
- Drop deprecated qr_code_scanner() method
- Add helper to add background color on image


1.2 (2017-03-09)
Expand Down
21 changes: 21 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,24 @@ How To use ZbarLight
codes = zbarlight.scan_codes('qrcode', image)
print('QR codes: %s' % codes)
Troubleshooting
===============

In some case ``zbarlight`` will not be able to detect the 1D or 2D code in an image, one of the known cause is that the
image background color is the same as the foreground color after conversion to grey scale (it's happen on images with
alpha channel). You can use the ``copy_image_on_background`` function to add a background color on your image.

.. code-block:: python
from PIL import Image
import zbarlight
file_path = './tests/fixtures/two_qr_codes.png'
with open(file_path, 'rb') as image_file:
image = Image.open(image_file)
image.load()
new_image = zbarlight.copy_image_on_background(image, color=zbarlight.WHITE) # <<<<<<<<<<<<<<<< Add this line <<<<
codes = zbarlight.scan_codes('qrcode', new_image)
print('QR codes: %s' % codes)
2 changes: 1 addition & 1 deletion docs/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ Reference
=========

.. automodule:: zbarlight
:members: scan_codes
:members: scan_codes, copy_image_on_background
27 changes: 26 additions & 1 deletion src/zbarlight/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@


__version__ = pkg_resources.get_distribution('zbarlight').version
__ALL__ = ['Symbologies', 'UnknownSymbologieError', 'scan_codes']
__ALL__ = [
'Symbologies',
'UnknownSymbologieError',
'scan_codes',
'copy_image_on_background',
'BLACK',
'WHITE',
]

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)


class UnknownSymbologieError(Exception):
Expand Down Expand Up @@ -42,3 +52,18 @@ def scan_codes(code_type, image):
if not symbologie:
raise UnknownSymbologieError('Unknown Symbologie: %s' % code_type)
return zbar_code_scanner(symbologie, raw, width, height)


def copy_image_on_background(image, color=WHITE):
"""Create a new image by copying the image on a *color* background
Args:
image (PIL.Image.Image): Image to copy
color (tuple): Background color usually WHITE or BLACK
Returns:
PIL.Image.Image
"""
background = Image.new("RGB", image.size, color)
background.paste(image, mask=image.split()[3])
return background
Binary file added tests/fixtures/sample_need_white_background.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 21 additions & 2 deletions tests/test_scan_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ class ScanCodeTestCase(unittest.TestCase):
def assertIsNone(self, obj, msg=None): # Python 2.6 hack
return self.assertTrue(obj is None, '%s is not None' % repr(obj))

def get_image(self, name):
def get_image(self, name, ext='png'):
return pil_image(
os.path.join(os.path.dirname(__file__), 'fixtures', '{0}.png'.format(name))
os.path.join(os.path.dirname(__file__), 'fixtures', '{0}.{1}'.format(name, ext))
)

def test_no_qr_code(self):
Expand Down Expand Up @@ -59,3 +59,22 @@ def test_unknown_symbology(self):
zbarlight.UnknownSymbologieError,
zbarlight.scan_codes, 'not-a-zbar-symbologie', image,
)

def test_need_white_background(self):
"""
User submitted sample that can only be decoded after add a white background
"""
# Not working
image = self.get_image('sample_need_white_background')

self.assertEqual(
sorted(zbarlight.scan_codes('qrcode', image) or []),
[],
)

# Working when adding white background
image_with_background = zbarlight.copy_image_on_background(image)
self.assertEqual(
sorted(zbarlight.scan_codes('qrcode', image_with_background) or []),
sorted([b'http://en.m.wikipedia.org']),
)

0 comments on commit 873dfaf

Please sign in to comment.