- 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

View File

@ -36,6 +36,7 @@
static void doBasicDemo(void);
static void doVarietyDemo(void);
static void doSegmentDemo(void);
static void doMaskDemo(void);
static void printQr(const uint8_t qrcode[]);
@ -45,6 +46,7 @@ int main(void) {
doBasicDemo();
doVarietyDemo();
doSegmentDemo();
doMaskDemo();
return EXIT_SUCCESS;
}
@ -66,15 +68,6 @@ static void doBasicDemo(void) {
// Creates a variety of QR Codes that exercise different features of the library, and prints each one to the console.
static void doVarietyDemo(void) {
{ // Project Nayuki URL
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
bool ok = qrcodegen_encodeText("https://www.nayuki.io/", tempBuffer, qrcode,
qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_3, true);
if (ok)
printQr(qrcode);
}
{ // Numeric mode encoding (3.33 bits per digit)
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
@ -93,29 +86,12 @@ static void doVarietyDemo(void) {
printQr(qrcode);
}
{ // Unicode text as UTF-8, and different masks
{ // Unicode text as UTF-8
const char *text = "\xE3\x81\x93\xE3\x82\x93\xE3\x81\xAB\xE3\x81\xA1wa\xE3\x80\x81\xE4\xB8\x96\xE7\x95\x8C\xEF\xBC\x81\x20\xCE\xB1\xCE\xB2\xCE\xB3\xCE\xB4";
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
bool ok;
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_QUARTILE, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_0, true);
if (ok)
printQr(qrcode);
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_QUARTILE, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_1, true);
if (ok)
printQr(qrcode);
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_QUARTILE, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_5, true);
if (ok)
printQr(qrcode);
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_QUARTILE, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_7, true);
bool ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_QUARTILE, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
if (ok)
printQr(qrcode);
}
@ -260,6 +236,60 @@ static void doSegmentDemo(void) {
}
// Creates QR Codes with the same size and contents but different mask patterns.
static void doMaskDemo(void) {
{ // Project Nayuki URL
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
bool ok;
ok = qrcodegen_encodeText("https://www.nayuki.io/", tempBuffer, qrcode,
qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
if (ok)
printQr(qrcode);
ok = qrcodegen_encodeText("https://www.nayuki.io/", tempBuffer, qrcode,
qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_3, true);
if (ok)
printQr(qrcode);
}
{ // Chinese text as UTF-8
const char *text =
"\xE7\xB6\xAD\xE5\x9F\xBA\xE7\x99\xBE\xE7\xA7\x91\xEF\xBC\x88\x57\x69\x6B\x69\x70"
"\x65\x64\x69\x61\xEF\xBC\x8C\xE8\x81\x86\xE8\x81\xBD\x69\x2F\xCB\x8C\x77\xC9\xAA"
"\x6B\xE1\xB5\xBB\xCB\x88\x70\x69\xCB\x90\x64\x69\x2E\xC9\x99\x2F\xEF\xBC\x89\xE6"
"\x98\xAF\xE4\xB8\x80\xE5\x80\x8B\xE8\x87\xAA\xE7\x94\xB1\xE5\x85\xA7\xE5\xAE\xB9"
"\xE3\x80\x81\xE5\x85\xAC\xE9\x96\x8B\xE7\xB7\xA8\xE8\xBC\xAF\xE4\xB8\x94\xE5\xA4"
"\x9A\xE8\xAA\x9E\xE8\xA8\x80\xE7\x9A\x84\xE7\xB6\xB2\xE8\xB7\xAF\xE7\x99\xBE\xE7"
"\xA7\x91\xE5\x85\xA8\xE6\x9B\xB8\xE5\x8D\x94\xE4\xBD\x9C\xE8\xA8\x88\xE7\x95\xAB";
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
bool ok;
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_0, true);
if (ok)
printQr(qrcode);
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_1, true);
if (ok)
printQr(qrcode);
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_5, true);
if (ok)
printQr(qrcode);
ok = qrcodegen_encodeText(text, tempBuffer, qrcode,
qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_7, true);
if (ok)
printQr(qrcode);
}
}
// Prints the given QR Code to the console.
static void printQr(const uint8_t qrcode[]) {
int size = qrcodegen_getSize(qrcode);

View File

@ -139,25 +139,6 @@ QrCode::QrCode(int ver, Ecc ecl, const vector<uint8_t> &dataCodewords, int mask)
}
QrCode::QrCode(const QrCode &qr, int mask) :
// Copy scalar fields
version(qr.version),
size(qr.size),
errorCorrectionLevel(qr.errorCorrectionLevel),
// Handle grid fields
modules(qr.modules),
isFunction(qr.isFunction) {
// Check arguments
if (mask < -1 || mask > 7)
throw "Mask value out of range";
// Handle masking
applyMask(qr.mask); // Undo old mask
this->mask = handleConstructorMasking(mask);
}
int QrCode::getVersion() const {
return version;
}

View File

@ -132,14 +132,6 @@ class QrCode final {
public: QrCode(int ver, Ecc ecl, const std::vector<std::uint8_t> &dataCodewords, int mask);
/*
* 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.
*/
public: QrCode(const QrCode &qr, int mask);
/*---- Public instance methods ----*/

View File

@ -42,6 +42,7 @@ using qrcodegen::QrSegment;
static void doBasicDemo();
static void doVarietyDemo();
static void doSegmentDemo();
static void doMaskDemo();
static void printQr(const QrCode &qr);
@ -51,6 +52,7 @@ int main() {
doBasicDemo();
doVarietyDemo();
doSegmentDemo();
doMaskDemo();
return EXIT_SUCCESS;
}
@ -69,10 +71,6 @@ static void doBasicDemo() {
// Creates a variety of QR Codes that exercise different features of the library, and prints each one to the console.
static void doVarietyDemo() {
// Project Nayuki URL
const QrCode qr0 = QrCode::encodeText("https://www.nayuki.io/", QrCode::Ecc::HIGH);
printQr(QrCode(qr0, 3)); // Change mask, forcing to mask #3
// Numeric mode encoding (3.33 bits per digit)
const QrCode qr1 = QrCode::encodeText("314159265358979323846264338327950288419716939937510", QrCode::Ecc::MEDIUM);
printQr(qr1);
@ -81,12 +79,9 @@ static void doVarietyDemo() {
const QrCode qr2 = QrCode::encodeText("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", QrCode::Ecc::HIGH);
printQr(qr2);
// Unicode text as UTF-8, and different masks
// Unicode text as UTF-8
const QrCode qr3 = QrCode::encodeText("\xE3\x81\x93\xE3\x82\x93\xE3\x81\xAB\xE3\x81\xA1wa\xE3\x80\x81\xE4\xB8\x96\xE7\x95\x8C\xEF\xBC\x81\x20\xCE\xB1\xCE\xB2\xCE\xB3\xCE\xB4", QrCode::Ecc::QUARTILE);
printQr(QrCode(qr3, 0));
printQr(QrCode(qr3, 1));
printQr(QrCode(qr3, 5));
printQr(QrCode(qr3, 7));
printQr(qr3);
// Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
const QrCode qr4 = QrCode::encodeText(
@ -163,6 +158,29 @@ static void doSegmentDemo() {
}
// Creates QR Codes with the same size and contents but different mask patterns.
static void doMaskDemo() {
// Project Nayuki URL
std::vector<QrSegment> segs0 = QrSegment::makeSegments("https://www.nayuki.io/");
printQr(QrCode::encodeSegments(segs0, QrCode::Ecc::HIGH, 1, 40, -1, true)); // Automatic mask
printQr(QrCode::encodeSegments(segs0, QrCode::Ecc::HIGH, 1, 40, 3, true)); // Force mask 3
// Chinese text as UTF-8
std::vector<QrSegment> segs1 = QrSegment::makeSegments(
"\xE7\xB6\xAD\xE5\x9F\xBA\xE7\x99\xBE\xE7\xA7\x91\xEF\xBC\x88\x57\x69\x6B\x69\x70"
"\x65\x64\x69\x61\xEF\xBC\x8C\xE8\x81\x86\xE8\x81\xBD\x69\x2F\xCB\x8C\x77\xC9\xAA"
"\x6B\xE1\xB5\xBB\xCB\x88\x70\x69\xCB\x90\x64\x69\x2E\xC9\x99\x2F\xEF\xBC\x89\xE6"
"\x98\xAF\xE4\xB8\x80\xE5\x80\x8B\xE8\x87\xAA\xE7\x94\xB1\xE5\x85\xA7\xE5\xAE\xB9"
"\xE3\x80\x81\xE5\x85\xAC\xE9\x96\x8B\xE7\xB7\xA8\xE8\xBC\xAF\xE4\xB8\x94\xE5\xA4"
"\x9A\xE8\xAA\x9E\xE8\xA8\x80\xE7\x9A\x84\xE7\xB6\xB2\xE8\xB7\xAF\xE7\x99\xBE\xE7"
"\xA7\x91\xE5\x85\xA8\xE6\x9B\xB8\xE5\x8D\x94\xE4\xBD\x9C\xE8\xA8\x88\xE7\x95\xAB");
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, 1, 40, 0, true)); // Force mask 0
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, 1, 40, 1, true)); // Force mask 1
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, 1, 40, 5, true)); // Force mask 5
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, 1, 40, 7, true)); // Force mask 7
}
// Prints the given QR Code to the console.
static void printQr(const QrCode &qr) {
int border = 4;

View File

@ -222,38 +222,6 @@ public final class QrCode {
}
/**
* Creates a new QR Code symbol based on the specified 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.
* @param qr the existing QR Code to copy and modify
* @param mask the new mask pattern, 0 to 7 to force a fixed choice or -1 for an automatic choice
* @throws NullPointerException if the QR Code is {@code null}
* @throws IllegalArgumentException if the mask value is out of range
*/
public QrCode(QrCode qr, int mask) {
// Check arguments
Objects.requireNonNull(qr);
if (mask < -1 || mask > 7)
throw new IllegalArgumentException("Mask value out of range");
// Copy scalar fields
version = qr.version;
size = qr.size;
errorCorrectionLevel = qr.errorCorrectionLevel;
// Handle grid fields
isFunction = qr.isFunction; // Shallow copy because the data is read-only
modules = qr.modules.clone(); // Deep copy
for (int i = 0; i < modules.length; i++)
modules[i] = modules[i].clone();
// Handle masking
applyMask(qr.mask); // Undo old mask
this.mask = handleConstructorMasking(mask);
}
/*---- Public instance methods ----*/

View File

@ -45,6 +45,7 @@ public final class QrCodeGeneratorDemo {
doBasicDemo();
doVarietyDemo();
doSegmentDemo();
doMaskDemo();
}
@ -72,11 +73,6 @@ public final class QrCodeGeneratorDemo {
private static void doVarietyDemo() throws IOException {
QrCode qr;
// Project Nayuki URL
qr = QrCode.encodeText("https://www.nayuki.io/", QrCode.Ecc.HIGH);
qr = new QrCode(qr, 3); // Change mask, forcing to mask #3
writePng(qr.toImage(8, 6), "project-nayuki-QR.png");
// Numeric mode encoding (3.33 bits per digit)
qr = QrCode.encodeText("314159265358979323846264338327950288419716939937510", QrCode.Ecc.MEDIUM);
writePng(qr.toImage(13, 1), "pi-digits-QR.png");
@ -85,12 +81,9 @@ public final class QrCodeGeneratorDemo {
qr = QrCode.encodeText("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", QrCode.Ecc.HIGH);
writePng(qr.toImage(10, 2), "alphanumeric-QR.png");
// Unicode text as UTF-8, and different masks
// Unicode text as UTF-8
qr = QrCode.encodeText("こんにちwa、世界 αβγδ", QrCode.Ecc.QUARTILE);
writePng(new QrCode(qr, 0).toImage(10, 3), "unicode-mask0-QR.png");
writePng(new QrCode(qr, 1).toImage(10, 3), "unicode-mask1-QR.png");
writePng(new QrCode(qr, 5).toImage(10, 3), "unicode-mask5-QR.png");
writePng(new QrCode(qr, 7).toImage(10, 3), "unicode-mask7-QR.png");
writePng(qr.toImage(10, 3), "unicode-QR.png");
// Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
qr = QrCode.encodeText(
@ -158,6 +151,31 @@ public final class QrCodeGeneratorDemo {
}
// Creates QR Codes with the same size and contents but different mask patterns.
private static void doMaskDemo() throws IOException {
QrCode qr;
List<QrSegment> segs;
// Project Nayuki URL
segs = QrSegment.makeSegments("https://www.nayuki.io/");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.HIGH, 1, 40, -1, true); // Automatic mask
writePng(qr.toImage(8, 6), "project-nayuki-automask-QR.png");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.HIGH, 1, 40, 3, true); // Force mask 3
writePng(qr.toImage(8, 6), "project-nayuki-mask3-QR.png");
// Chinese text as UTF-8
segs = QrSegment.makeSegments("維基百科Wikipedia聆聽i/ˌwɪkᵻˈpiːdi.ə/)是一個自由內容、公開編輯且多語言的網路百科全書協作計畫");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, 1, 40, 0, true); // Force mask 0
writePng(qr.toImage(10, 3), "unicode-mask0-QR.png");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, 1, 40, 1, true); // Force mask 1
writePng(qr.toImage(10, 3), "unicode-mask1-QR.png");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, 1, 40, 5, true); // Force mask 5
writePng(qr.toImage(10, 3), "unicode-mask5-QR.png");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, 1, 40, 7, true); // Force mask 7
writePng(qr.toImage(10, 3), "unicode-mask7-QR.png");
}
// Helper function to reduce code duplication.
private static void writePng(BufferedImage img, String filepath) throws IOException {
ImageIO.write(img, "png", new File(filepath));

View File

@ -31,7 +31,6 @@
* - Function encodeBinary(list<byte> data, QrCode.Ecc ecl) -> QrCode
* - Function encodeSegments(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(list<int> datacodewords, int mask, int version, QrCode.Ecc ecl)
* - Fields int version, size, mask
* - Field QrCode.Ecc errorCorrectionLevel
@ -64,35 +63,19 @@ var qrcodegen = new function() {
* with associated static functions to create a QR Code from user-supplied textual or binary data.
* This class covers the QR Code model 2 specification, supporting all versions (sizes)
* from 1 to 40, all 4 error correction levels.
*
* This constructor can be called in one of two ways:
* - new QrCode(datacodewords, mask, version, errCorLvl):
* 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.encodeSegments() function.
* - new QrCode(qr, mask):
* 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.
* This constructor 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.encodeSegments() function.
*/
this.QrCode = function(initData, mask, version, errCorLvl) {
this.QrCode = function(datacodewords, mask, version, errCorLvl) {
/*---- Constructor ----*/
// Check arguments and handle simple scalar fields
if (mask < -1 || mask > 7)
throw "Mask value out of range";
if (initData instanceof Array) {
if (version < 1 || version > 40)
throw "Version value out of range";
} else if (initData instanceof qrcodegen.QrCode) {
if (version != undefined || errCorLvl != undefined)
throw "Values must be undefined";
version = initData.version;
errCorLvl = initData.errorCorrectionLevel;
} else
throw "Invalid initial data";
var size = version * 4 + 17;
// Initialize both grids to be size*size arrays of Boolean false
@ -106,22 +89,10 @@ var qrcodegen = new function() {
isFunction.push(row.slice());
}
// Handle grid fields
if (initData instanceof Array) {
// Draw function patterns, draw all codewords
// Handle grid fields, draw function patterns, draw all codewords
drawFunctionPatterns();
var allCodewords = appendErrorCorrection(initData);
var allCodewords = appendErrorCorrection(datacodewords);
drawCodewords(allCodewords);
} else if (initData instanceof qrcodegen.QrCode) {
for (var y = 0; y < size; y++) {
for (var x = 0; x < size; x++) {
modules[y][x] = initData.getModule(x, y);
isFunction[y][x] = initData.isFunctionModule(x, y);
}
}
applyMask(initData.mask); // Undo old mask
} else
throw "Invalid initial data";
// Handle masking
if (mask == -1) { // Automatically choose best mask

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 ----

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,43 +134,27 @@ 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")
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
@ -181,10 +164,6 @@ class QrCode(object):
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
# Handle masking
if mask == -1: # Automatically choose best mask

View File

@ -35,6 +35,7 @@ fn main() {
do_basic_demo();
do_variety_demo();
do_segment_demo();
do_mask_demo();
}
@ -52,11 +53,6 @@ fn do_basic_demo() {
// Creates a variety of QR Codes that exercise different features of the library, and prints each one to the console.
fn do_variety_demo() {
// Project Nayuki URL
let qr = QrCode::encode_text("https://www.nayuki.io/", QrCodeEcc::High).unwrap();
let qr = QrCode::remask(&qr, Some(3)); // Change mask, forcing to mask #3
print_qr(&qr);
// Numeric mode encoding (3.33 bits per digit)
let qr = QrCode::encode_text("314159265358979323846264338327950288419716939937510", QrCodeEcc::Medium).unwrap();
print_qr(&qr);
@ -65,12 +61,9 @@ fn do_variety_demo() {
let qr = QrCode::encode_text("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", QrCodeEcc::High).unwrap();
print_qr(&qr);
// Unicode text as UTF-8, and different masks
// Unicode text as UTF-8
let qr = QrCode::encode_text("こんにちwa、世界 αβγδ", QrCodeEcc::Quartile).unwrap();
print_qr(&QrCode::remask(&qr, Some(0)));
print_qr(&QrCode::remask(&qr, Some(1)));
print_qr(&QrCode::remask(&qr, Some(5)));
print_qr(&QrCode::remask(&qr, Some(7)));
print_qr(&qr);
// Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
let qr = QrCode::encode_text(concat!(
@ -140,6 +133,28 @@ fn do_segment_demo() {
}
// Creates QR Codes with the same size and contents but different mask patterns.
fn do_mask_demo() {
// Project Nayuki URL
let segs = QrSegment::make_segments(&to_chars("https://www.nayuki.io/"));
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::High, 1, 40, None, true).unwrap(); // Automatic mask
print_qr(&qr);
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::High, 1, 40, Some(3), true).unwrap(); // Force mask 3
print_qr(&qr);
// Chinese text as UTF-8
let segs = QrSegment::make_segments(&to_chars("維基百科Wikipedia聆聽i/ˌwɪkᵻˈpiːdi.ə/)是一個自由內容、公開編輯且多語言的網路百科全書協作計畫"));
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, 1, 40, Some(0), true).unwrap(); // Force mask 0
print_qr(&qr);
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, 1, 40, Some(1), true).unwrap(); // Force mask 1
print_qr(&qr);
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, 1, 40, Some(5), true).unwrap(); // Force mask 5
print_qr(&qr);
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, 1, 40, Some(7), true).unwrap(); // Force mask 7
print_qr(&qr);
}
/*---- Utilities ----*/
// Prints the given QrCode object to the console.

View File

@ -193,30 +193,6 @@ impl QrCode {
}
// 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.
pub fn remask(qr: &QrCode, mask: Option<u8>) -> QrCode {
// Check arguments
assert!(mask == None || mask.unwrap() <= 7, "Mask out of range");
// Copy fields
let mut result = QrCode {
version: qr.version,
size: qr.size,
mask: 0, // Dummy value
errorcorrectionlevel: qr.errorcorrectionlevel,
modules: qr.modules.clone(),
isfunction: qr.isfunction.clone(),
};
// Handle masking
result.apply_mask(qr.mask); // Undo old mask
result.handle_constructor_masking(mask);
result
}
// Returns this QR Code's version, in the range [1, 40].
pub fn version(&self) -> u8 {
self.version