- Deleted constructors/functions/code for remasking existing QrCode object (due to doubtful real-world usefulness): C++, Java, JavaScript, Python, Rust.

- Tweaked code and comments due to feature removal: JavaScript, Python.
- Updated demo programs to reflect new API usage and add new example: C, C++, Java, Python, Rust.
This commit is contained in:
Project Nayuki
2017-10-23 03:45:24 +00:00
parent c4c8d6ba45
commit b86466ecd5
11 changed files with 191 additions and 229 deletions
+24 -10
View File
@@ -35,6 +35,7 @@ def main():
do_basic_demo()
do_variety_demo()
do_segment_demo()
do_mask_demo()
def do_basic_demo():
@@ -51,11 +52,6 @@ def do_basic_demo():
def do_variety_demo():
"""Creates a variety of QR Codes that exercise different features of the library, and prints each one to the console."""
# Project Nayuki URL
qr = qrcodegen.QrCode.encode_text("https://www.nayuki.io/", qrcodegen.QrCode.Ecc.HIGH)
qr = qrcodegen.QrCode(qrcode=qr, mask=3) # Change mask, forcing to mask #3
print_qr(qr)
# Numeric mode encoding (3.33 bits per digit)
qr = qrcodegen.QrCode.encode_text("314159265358979323846264338327950288419716939937510", qrcodegen.QrCode.Ecc.MEDIUM)
print_qr(qr)
@@ -64,12 +60,9 @@ def do_variety_demo():
qr = qrcodegen.QrCode.encode_text("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", qrcodegen.QrCode.Ecc.HIGH)
print_qr(qr)
# Unicode text as UTF-8, and different masks
# Unicode text as UTF-8
qr = qrcodegen.QrCode.encode_text(u"\u3053\u3093\u306B\u3061\u0077\u0061\u3001\u4E16\u754C\uFF01\u0020\u03B1\u03B2\u03B3\u03B4", qrcodegen.QrCode.Ecc.QUARTILE)
print_qr(qrcodegen.QrCode(qrcode=qr, mask=0))
print_qr(qrcodegen.QrCode(qrcode=qr, mask=1))
print_qr(qrcodegen.QrCode(qrcode=qr, mask=5))
print_qr(qrcodegen.QrCode(qrcode=qr, mask=7))
print_qr(qr)
# Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
qr = qrcodegen.QrCode.encode_text(
@@ -153,6 +146,27 @@ def do_segment_demo():
print_qr(qr)
def do_mask_demo():
"""Creates QR Codes with the same size and contents but different mask patterns."""
# Project Nayuki URL
segs = qrcodegen.QrSegment.make_segments("https://www.nayuki.io/")
print_qr(qrcodegen.QrCode.encode_segments(segs, qrcodegen.QrCode.Ecc.HIGH, mask=-1)) # Automatic mask
print_qr(qrcodegen.QrCode.encode_segments(segs, qrcodegen.QrCode.Ecc.HIGH, mask=3)) # Force mask 3
# Chinese text as UTF-8
segs = qrcodegen.QrSegment.make_segments(
u"\u7DAD\u57FA\u767E\u79D1\uFF08\u0057\u0069\u006B\u0069\u0070\u0065\u0064\u0069\u0061\uFF0C"
"\u8046\u807D\u0069\u002F\u02CC\u0077\u026A\u006B\u1D7B\u02C8\u0070\u0069\u02D0\u0064\u0069"
"\u002E\u0259\u002F\uFF09\u662F\u4E00\u500B\u81EA\u7531\u5167\u5BB9\u3001\u516C\u958B\u7DE8"
"\u8F2F\u4E14\u591A\u8A9E\u8A00\u7684\u7DB2\u8DEF\u767E\u79D1\u5168\u66F8\u5354\u4F5C\u8A08"
"\u756B")
print_qr(qrcodegen.QrCode.encode_segments(segs, qrcodegen.QrCode.Ecc.MEDIUM, mask=0)) # Force mask 0
print_qr(qrcodegen.QrCode.encode_segments(segs, qrcodegen.QrCode.Ecc.MEDIUM, mask=1)) # Force mask 1
print_qr(qrcodegen.QrCode.encode_segments(segs, qrcodegen.QrCode.Ecc.MEDIUM, mask=5)) # Force mask 5
print_qr(qrcodegen.QrCode.encode_segments(segs, qrcodegen.QrCode.Ecc.MEDIUM, mask=7)) # Force mask 7
# ---- Utilities ----
+18 -39
View File
@@ -31,7 +31,6 @@ This module "qrcodegen", public members:
- Function encode_binary(bytes data, QrCode.Ecc ecl) -> QrCode
- Function encode_segments(list<QrSegment> segs, QrCode.Ecc ecl,
int minversion=1, int maxversion=40, mask=-1, boostecl=true) -> QrCode
- Constructor QrCode(QrCode qr, int mask)
- Constructor QrCode(bytes datacodewords, int mask, int version, QrCode.Ecc ecl)
- Method get_version() -> int
- Method get_size() -> int
@@ -135,56 +134,36 @@ class QrCode(object):
assert len(bb) % 8 == 0
# Create the QR Code symbol
return QrCode(None, bb.get_bytes(), mask, version, ecl)
return QrCode(bb.get_bytes(), mask, version, ecl)
# ---- Constructor ----
def __init__(self, qrcode=None, datacodewords=None, mask=None, version=None, errcorlvl=None):
"""This constructor can be called in one of two ways:
- QrCode(datacodewords=list<int>, mask=int, version=int, errcorlvl=QrCode.Ecc):
Creates a new QR Code symbol with the given version number, error correction level, binary data array,
and mask number. This is a cumbersome low-level constructor that should not be invoked directly by the user.
To go one level up, see the QrCode.encode_segments() function.
- QrCode(qrcode=QrCode, mask=int):
Creates a new QR Code symbol based on the given existing object, but with a potentially different
mask pattern. The version, error correction level, codewords, etc. of the newly created object are
all identical to the argument object; only the mask may differ.
In both cases, mask = -1 is for automatic choice or 0 to 7 for fixed choice."""
def __init__(self, datacodewords, mask, version, errcorlvl):
"""Creates a new QR Code symbol with the given version number, error correction level, binary data array,
and mask number. mask = -1 is for automatic choice, or 0 to 7 for fixed choice. This is a cumbersome low-level constructor
that should not be invoked directly by the user. To go one level up, see the QrCode.encode_segments() function."""
# Check arguments and handle simple scalar fields
if not (-1 <= mask <= 7):
raise ValueError("Mask value out of range")
if datacodewords is not None and qrcode is None:
if not (1 <= version <= 40):
raise ValueError("Version value out of range")
if not isinstance(errcorlvl, QrCode.Ecc):
raise TypeError("QrCode.Ecc expected")
elif qrcode is not None and datacodewords is None:
if version is not None or errcorlvl is not None:
raise ValueError("Values must be None")
version = qrcode._version
errcorlvl = qrcode._errcorlvl
else:
raise ValueError("Exactly one of datacodewords or qrcode must be not None")
if not (1 <= version <= 40):
raise ValueError("Version value out of range")
if not isinstance(errcorlvl, QrCode.Ecc):
raise TypeError("QrCode.Ecc expected")
self._version = version
self._errcorlvl = errcorlvl
self._size = version * 4 + 17
if datacodewords is not None: # Render from scratch a QR Code based on data codewords
if len(datacodewords) != QrCode._get_num_data_codewords(version, errcorlvl):
raise ValueError("Invalid array length")
# Initialize grids of modules
self._modules = [[False] * self._size for _ in range(self._size)] # The modules of the QR symbol; start with entirely white grid
self._isfunction = [[False] * self._size for _ in range(self._size)] # Indicates function modules that are not subjected to masking
# Draw function patterns, draw all codewords
self._draw_function_patterns()
allcodewords = self._append_error_correction(datacodewords)
self._draw_codewords(allcodewords)
elif qrcode is not None: # Modify the mask of an existing QR Code
self._modules = [list(row) for row in qrcode._modules] # Deep copy
self._isfunction = qrcode._isfunction # Shallow copy because the data is read-only
self._apply_mask(qrcode._mask) # Undo existing mask
if len(datacodewords) != QrCode._get_num_data_codewords(version, errcorlvl):
raise ValueError("Invalid array length")
# Initialize grids of modules
self._modules = [[False] * self._size for _ in range(self._size)] # The modules of the QR symbol; start with entirely white grid
self._isfunction = [[False] * self._size for _ in range(self._size)] # Indicates function modules that are not subjected to masking
# Draw function patterns, draw all codewords
self._draw_function_patterns()
allcodewords = self._append_error_correction(datacodewords)
self._draw_codewords(allcodewords)
# Handle masking
if mask == -1: # Automatically choose best mask