1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
require 'rqrcode'
require 'barby/barcode'
module Barby
#QrCode is a thin wrapper around the RQRCode library
class QrCode < Barcode2D
#Maximum sizes for each correction level for binary data
#It's an array
SIZES = {
#L M Q H
1 => [17, 14, 11, 7], 2 => [32, 26, 20, 14],
3 => [53, 42, 32, 24], 4 => [78, 62, 46, 34],
5 => [106, 84, 60, 44], 6 => [134, 106, 74, 58],
7 => [154, 122, 86, 64], 8 => [192, 152, 108, 84],
9 => [230, 180, 130, 98], 10 => [271, 213, 151, 119],
11 => [321, 251, 177, 137], 12 => [367, 287, 203, 155],
13 => [425, 331, 241, 177], 14 => [458, 362, 258, 194],
15 => [520, 412, 292, 220], 16 => [586, 450, 322, 250],
17 => [644, 504, 364, 280], 18 => [718, 560, 394, 310],
19 => [792, 624, 442, 338], 20 => [858, 666, 482, 382],
21 => [929, 711, 509, 403], 22 => [1003, 779, 565, 439],
23 => [1091, 857, 611, 461], 24 => [1171, 911, 661, 511],
25 => [1273, 997, 715, 535], 26 => [1367, 1059, 751, 593],
27 => [1465, 1125, 805, 625], 28 => [1528, 1190, 868, 658],
29 => [1628, 1264, 908, 698], 30 => [1732, 1370, 982, 742],
31 => [1840, 1452, 1030, 790], 32 => [1952, 1538, 1112, 842],
33 => [2068, 1628, 1168, 898], 34 => [2188, 1722, 1228, 958],
35 => [2303, 1809, 1283, 983], 36 => [2431, 1911, 1351, 1051],
37 => [2563, 1989, 1423, 1093], 38 => [2699, 2099, 1499, 1139],
39 => [2809, 2213, 1579, 1219], 40 => [2953, 2331, 1663, 1273]
}.sort
LEVELS = { :l => 0, :m => 1, :q => 2, :h => 3 }
attr_reader :data
attr_writer :level, :size
def initialize(data, options={})
self.data = data
options.each{|k,v| send("#{k}=", v) }
raise(ArgumentError, "data too large") unless size
end
def data=(data)
@data = data
end
def encoding
rqrcode.modules.map{|r| r.inject(''){|s,m| s << (m ? '1' : '0') } }
end
#Error correction level
#Can be one of [:l, :m, :q, :h] (7%, 15%, 25%, 30%)
def level
@level || :l
end
def size
#@size is only used for manual override, if it's not set
#manually the size is always dynamic, calculated from the
#length of the data
return @size if @size
level_index = LEVELS[level]
length = data.length
found_size = nil
SIZES.each do |size,max_values|
if max_values[level_index] >= length
found_size = size
break
end
end
found_size
end
def to_s
data[0,20]
end
private
#Generate an RQRCode object with the available values
def rqrcode
RQRCode::QRCode.new(data, :level => level, :size => size)
end
end
end
|