Class: QREncoder::QRCode
- Inherits:
-
Object
- Object
- QREncoder::QRCode
- Defined in:
- lib/qrencoder/qrcode.rb,
ext/qrencoder_ext/qrencoder_ext.c
Overview
Stores and represents data, points, and/or pixels for a QRCode
Instance Method Summary collapse
- #canvas(options = {}) ⇒ Object
-
#data ⇒ Object
Returns the raw data of the QRcode within a single array of width*width elements.
-
#new(string, version, eclevel, mode, case_sensitive) ⇒ Object
constructor
Encodes a QR code from a string.
-
#initialize_copy(orig) ⇒ Object
Handles
clone
anddup
. -
#pixels ⇒ Object
Returns the QRcode as an array of rows where each item in a row represents the value of the pixel (1 = black, 0 = white).
-
#png(options = {}) ⇒ Object
Returns an instance of PNG, which can be saved to a file with PNG#save or converted to a blob for inline file transfer with PNG#to_blob.
-
#points ⇒ Object
Returns the black pixels of the encoded image as an array of coordinate pairs.
-
#save_png(path) ⇒ Object
Shortcut to save the QRcode as a PNG at
path
using default options. -
#version ⇒ Object
Version of the symbol.
-
#width ⇒ Object
(also: #height)
Width of the symbol in modules.
Constructor Details
#new(string, version, eclevel, mode, case_sensitive) ⇒ Object
Encodes a QR code from a string.
There are 5 required arguments:
- string
-
the string to encode
- version
-
the version of the QR Code
- error correction level
-
an integer representing an error correction level
- encoding mode
-
an integer representing the encoding mode
- case sensitivity
-
1 (case sensitive) or 0 (case insensitive)
Version
What is the version? Each QRCode is made up of modules which are the basic display element of a QRCode and may be made up of 1 or more pixels (here, it’s just 1 module is 1 pixel). Version 1 is a 21x21 module square, while the maximum version 40 is 177x177 modules. The full module reference is here www.denso-wave.com/qrcode/vertable1-e.html
Should you encode more text than can fit in a module, the encoder will scale up to the smallest version able to contain your data. Unless you want to specifically fix your barcode to a certain version, it’s fine to just set the version argument to 1 and let the algorithm figure out the proper size.
Error correction
The following four constants can be specified for error correction levels, each specified with the maximum approximate error rate they can compensate for, as well as the maximum capacity of an 8-bit data QR Code with the error encoding:
-
QR_ECLEVEL_L
- 7%/2953 [default] -
QR_ECLEVEL_M
- 15%/2331 -
QR_ECLEVEL_Q
- 25%/1663 -
QR_ECLEVEL_H
- 30%/1273
Higher error rates are suitable for applications where the QR Code is likely to be smudged or damaged, but as is apparent here, they can radically reduce the maximum data capacity of a QR Code.
Encoding mode
There are 4 possible encodings for a QR Code which can modify the maximum data capacity. These are specified with four possible Constants, each listed here with the maximum capacity available for that encoding at the lowest error correction rate.
-
QR_MODE_NUM
- Numeric/7089 -
QR_MODE_AN
- Alphanumeric/4296 -
QR_MODE_8
- 8-bit ASCII/2953 [default] -
QR_MODE_KANJI
- Kanji (JIS-1 & 2)/1817
Note that the QR Code specification seemingly predates the rise and triumph of UTF-8, and the specification makes no requirement that writers and readers use ISO-8859-1 or UTF-8 or whatever to interpret the data in a barcode. If you encode in UTF-8, it might be read as ISO-8859-1 or not.
Case sensitivity
Encoding can either be case sensitive (1) or not (0). Without case sensitivity turned on, many decoders will view all alphabetic characters as uppercase.
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'ext/qrencoder_ext/qrencoder_ext.c', line 235
static VALUE qr_initialize(VALUE self, VALUE _string, VALUE _version, VALUE _eclevel, VALUE _hint, VALUE _casesensitive) {
const char *string = StringValuePtr(_string);
int version = FIX2INT(_version);
int eclevel = FIX2INT(_eclevel);
int hint = FIX2INT(_hint);
int casesensitive = FIX2INT(_casesensitive);
int error = errno;
QRcode *code;
QRinput *input = QRinput_new2(version, eclevel);
QRinput_append(input, hint, strlen(string), string);
code = QRcode_encodeInput(input);
QRinput_free(input);
if (errno != error && errno == 22) {
rb_raise(rb_eArgError, "input was too long");
}
if (NULL == code) {
rb_raise(rb_eArgError, "could not encode input");
}
if (DATA_PTR(self)) {
QRcode_free(DATA_PTR(self));
DATA_PTR(self) = NULL;
}
DATA_PTR(self) = code;
return self;
}
|
Instance Method Details
#canvas(options = {}) ⇒ Object
28 29 30 |
# File 'lib/qrencoder/qrcode.rb', line 28 def canvas(={}) png().canvas end |
#data ⇒ Object
Returns the raw data of the QRcode within a single array of width*width elements. Each item is a byte of data of which only the least significant bit is the pixel. The full use of each bit from Least Significant to Most is as follows
-
1=black / 0=white
-
data and ecc code area
-
format information
-
version information
-
timing pattern
-
alignment pattern
-
finder pattern and separator
-
non-data modules (format, timing, etc.)
This structure allows the QRcode spec to store multiple types of information within the allocated output buffers, but you usually only care about the pixel color. For those cases, just use the pixels
or points
methods.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'ext/qrencoder_ext/qrencoder_ext.c', line 67
static VALUE _data(VALUE self) {
QRcode *qrcode;
VALUE out;
unsigned char *p, b;
int i, max;
Data_Get_Struct(self, QRcode, qrcode);
p = qrcode->data;
max = qrcode->width * qrcode->width;
out = rb_ary_new2(max);
for (i=0; i < max; i++) {
b = *p;
rb_ary_push(out, INT2FIX(b));
p++;
}
return out;
}
|
#initialize_copy(orig) ⇒ Object
Handles clone
and dup
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'ext/qrencoder_ext/qrencoder_ext.c', line 154
static VALUE qr_init_copy(VALUE copy, VALUE orig) {
QRcode *copy_qrcode;
QRcode *orig_qrcode;
if (copy == orig)
return copy;
Data_Get_Struct(orig, QRcode, orig_qrcode);
Data_Get_Struct(copy, QRcode, copy_qrcode);
MEMCPY(copy_qrcode, orig_qrcode, QRcode, 1);
/* Code will be freed by original object */
RDATA(copy)->dfree = NULL;
return copy;
}
|
#pixels ⇒ Object
Returns the QRcode as an array of rows where each item in a row represents the value of the pixel (1 = black, 0 = white)
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'ext/qrencoder_ext/qrencoder_ext.c', line 94
static VALUE _pixels(VALUE self) {
QRcode *qrcode;
VALUE out, row;
unsigned char *p;
int x, y, bit;
Data_Get_Struct(self, QRcode, qrcode);
p = qrcode->data;
out = rb_ary_new2(qrcode->width);
for (y=0; y < qrcode->width; y++) {
row = rb_ary_new2(qrcode->width);
for (x=0; x < qrcode->width; x++) {
bit = *p & 1;
rb_ary_push(row, INT2FIX(bit));
p++;
}
rb_ary_push(out, row);
}
return out;
}
|
#png(options = {}) ⇒ Object
Returns an instance of PNG, which can be saved to a file with PNG#save or converted to a blob for inline file transfer with PNG#to_blob.
Options:
- :margin
-
A pixel value for the margin around each side of the code. This should be 4 or greater. (default:
4
) - :transparent
-
Background transparency. Can be true or false. (default:
false
) - :pixels_per_module
-
Adjusts the entire PNG image by the given factor, integer. (default:
1
)
24 25 26 |
# File 'lib/qrencoder/qrcode.rb', line 24 def png(={}) PNG.new(self, ) end |
#points ⇒ Object
Returns the black pixels of the encoded image as an array of coordinate pairs.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'ext/qrencoder_ext/qrencoder_ext.c', line 125
static VALUE _points(VALUE self) {
QRcode *qrcode;
VALUE out, point;
unsigned char *p;
int x, y, bit;
Data_Get_Struct(self, QRcode, qrcode);
p = qrcode->data;
out = rb_ary_new2(qrcode->width);
for (y=0; y < qrcode->width; y++) {
for (x=0; x < qrcode->width; x++) {
bit = *p & 1;
if (bit) {
point = rb_ary_new2(2);
rb_ary_push(point, INT2FIX(x));
rb_ary_push(point, INT2FIX(y));
rb_ary_push(out, point);
}
p++;
}
}
return out;
}
|
#save_png(path) ⇒ Object
Shortcut to save the QRcode as a PNG at path
using default options.
For more control, or to specify non-default options, see QRCode#png
10 11 12 |
# File 'lib/qrencoder/qrcode.rb', line 10 def save_png(path) png.save(path) end |
#version ⇒ Object
Version of the symbol. A QR Code version indicates the size of the 2-D barcode in modules. See qrencode_string
for a more detailed description of the version. Note that the version returned might be larger than the version specified for an encode_string if the requested version is for a barcode too small to encode the data.
39 40 41 42 43 |
# File 'ext/qrencoder_ext/qrencoder_ext.c', line 39
static VALUE _version(VALUE self) {
QRcode *qrcode;
Data_Get_Struct(self, QRcode, qrcode);
return INT2FIX(qrcode->version);
}
|
#width ⇒ Object Also known as: height
Width of the symbol in modules. This value usually corresponds to 1 module is 1 pixel, but you could conceivably scale it up if you wanted to.
22 23 24 25 26 |
# File 'ext/qrencoder_ext/qrencoder_ext.c', line 22
static VALUE _width(VALUE self) {
QRcode *qrcode;
Data_Get_Struct(self, QRcode, qrcode);
return INT2FIX(qrcode->width);
}
|