Skip to content

Commit

Permalink
Merge pull request #16 from OUDON/feat/add-with-quiet-zone
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Add the option `with_quiet_zone`
  • Loading branch information
OUDON authored Aug 4, 2022
2 parents 68392b3 + 3bd7b10 commit 09b11e4
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 27 deletions.
33 changes: 11 additions & 22 deletions src/rmqrcode/qr_image.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
from PIL import Image, ImageDraw

from .enums.color import Color


class QRImage:
def __init__(self, qr, module_size=10):
self._module_size = module_size
self._img = Image.new(
"RGB", ((qr.width() + 4) * module_size, (qr.height() + 4) * module_size), (255, 255, 255)
)
self._make_image(qr)
qr_list = qr.to_list()
self._img = Image.new("RGB", (len(qr_list[0]) * module_size, len(qr_list) * module_size), (255, 255, 255))
self._make_image(qr_list)

def show(self):
self._img.show()
Expand All @@ -26,25 +23,17 @@ def get_ndarray(self):
def save(self, name):
self._img.save(name)

def _make_image(self, qr):
def _make_image(self, qr_list):
draw = ImageDraw.Draw(self._img)
for y in range(qr.height()):
for x in range(qr.width()):
r, g, b = 125, 125, 125
if qr.value_at(x, y) == Color.BLACK:
r, g, b = 0, 0, 0
elif qr.value_at(x, y) == Color.WHITE:
r, g, b, = (
255,
255,
255,
)
for y in range(len(qr_list)):
for x in range(len(qr_list[0])):
r, g, b = (0, 0, 0) if qr_list[y][x] else (255, 255, 255)
draw.rectangle(
xy=(
(x + 2) * self._module_size,
(y + 2) * self._module_size,
(x + 1 + 2) * self._module_size,
(y + 1 + 2) * self._module_size,
x * self._module_size,
y * self._module_size,
(x + 1) * self._module_size,
(y + 1) * self._module_size,
),
fill=(r, g, b),
)
37 changes: 32 additions & 5 deletions src/rmqrcode/rmqrcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@


class rMQR:
QUIET_ZONE_MODULES = 2

@staticmethod
def _init_logger():
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -72,7 +74,7 @@ def sort_key(x):
qr.make(data)
return qr

def __init__(self, version, ecc, logger=None):
def __init__(self, version, ecc, with_quiet_zone=True, logger=None):
self._logger = logger or rMQR._init_logger()

if not rMQR.validate_version(version):
Expand Down Expand Up @@ -109,10 +111,23 @@ def width(self):
def value_at(self, x, y):
return self._qr[y][x]

def to_list(self):
def to_list(self, with_quiet_zone=True):
res = []
if with_quiet_zone:
for y in range(self.QUIET_ZONE_MODULES):
res.append([0] * (self.width() + self.QUIET_ZONE_MODULES * 2))
for row in self._to_binary_list():
res.append([0] * self.QUIET_ZONE_MODULES + row + [0] * self.QUIET_ZONE_MODULES)
for y in range(self.QUIET_ZONE_MODULES):
res.append([0] * (self.width() + self.QUIET_ZONE_MODULES * 2))
else:
res = self._to_binary_list()
return res

def _to_binary_list(self):
return [list(map(lambda x: 1 if x == Color.BLACK else 0, column)) for column in self._qr]

def __str__(self):
def __str__(self, with_quiet_zone=True):
res = ""

show = {}
Expand All @@ -123,13 +138,25 @@ def __str__(self):
show[False] = "_"

res += f"rMQR Version R{self._height}x{self._width}:\n"
for i in range(self._height):
for j in range(self._width):
if with_quiet_zone:
res += (show[False] * (self.width() + self.QUIET_ZONE_MODULES * 2) + "\n") * self.QUIET_ZONE_MODULES

for i in range(self.height()):
if with_quiet_zone:
res += show[False] * self.QUIET_ZONE_MODULES

for j in range(self.width()):
if self._qr[i][j] in show:
res += show[self._qr[i][j]]
else:
res += self._qr[i][j]

if with_quiet_zone:
res += show[False] * self.QUIET_ZONE_MODULES
res += "\n"

if with_quiet_zone:
res += (show[False] * (self.width() + self.QUIET_ZONE_MODULES * 2) + "\n") * self.QUIET_ZONE_MODULES
return res

def _put_finder_pattern(self):
Expand Down
6 changes: 6 additions & 0 deletions tests/rmqrcode_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ def test_make(self):
qr = rMQR('R13x99', ErrorCorrectionLevel.M)
qr.make("abc")

assert len(qr.to_list(with_quiet_zone=True)) is 17
assert len(qr.to_list(with_quiet_zone=True)[0]) is 103

assert len(qr.to_list(with_quiet_zone=False)) is 13
assert len(qr.to_list(with_quiet_zone=False)[0]) is 99

def test_raise_too_long_error(self):
with pytest.raises(DataTooLongError) as e:
s = "a".ljust(200, "a")
Expand Down

0 comments on commit 09b11e4

Please sign in to comment.