Class: QREncoder::QRCode

Inherits:
Object
  • Object
show all
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)

Constructor Details

- (Object) new(string, version, eclevel, mode, case_sensitive)

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.



# File 'ext/qrencoder_ext/qrencoder_ext.c'

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");
}

Instance Method Details

- (Object) canvas(options = {})



28
29
30
# File 'lib/qrencoder/qrcode.rb', line 28

def canvas(options={})
  png(options).canvas
end

- (Object) data

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.



# File 'ext/qrencoder_ext/qrencoder_ext.c'

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++;
}

- (Object) initialize_copy

Handles clone and dup



# File 'ext/qrencoder_ext/qrencoder_ext.c'

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

- (Object) pixels

Returns the QRcode as an array of rows where each item in a row represents the value of the pixel (1 = black, 0 = white)



# File 'ext/qrencoder_ext/qrencoder_ext.c'

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++;
}

- (Object) png(options = {})

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(options={})
  PNG.new(self, options)
end

- (Object) points

Returns the black pixels of the encoded image as an array of coordinate pairs.



# File 'ext/qrencoder_ext/qrencoder_ext.c'

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);
}

- (Object) save_png(path)

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

- (Object) version

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.



# File 'ext/qrencoder_ext/qrencoder_ext.c'

static VALUE _version(VALUE self) {
  QRcode *qrcode;
  Data_Get_Struct(self, QRcode, qrcode);
  return INT2FIX(qrcode->version);
}

- (Object) width

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.



# File 'ext/qrencoder_ext/qrencoder_ext.c'

static VALUE _width(VALUE self) {
  QRcode *qrcode;
  Data_Get_Struct(self, QRcode, qrcode);
  return INT2FIX(qrcode->width);
}