- 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:
parent
c4c8d6ba45
commit
b86466ecd5
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ----*/
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ----*/
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ----
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue