Class: RQRCodeCore::QRCode
- Inherits:
-
Object
- Object
- RQRCodeCore::QRCode
- Extended by:
- Gem::Deprecate
- Defined in:
- lib/rqrcode_core/qrcode/qr_code.rb
Overview
Creation
QRCode objects expect only one required constructor parameter and an optional hash of any other. Here’s a few examples:
qr = RQRCodeCore::QRCode.new('hello world')
qr = RQRCodeCore::QRCode.new('hello world', size: 1, level: :m, mode: :alphanumeric)
Instance Attribute Summary collapse
-
#module_count ⇒ Object
readonly
Returns the value of attribute module_count.
-
#modules ⇒ Object
readonly
Returns the value of attribute modules.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Class Method Summary collapse
-
.count_max_data_bits(rs_blocks) ⇒ Object
:nodoc:.
-
.create_bytes(buffer, rs_blocks) ⇒ Object
:nodoc:.
-
.create_data(version, error_correct_level, data_list) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#checked?(row, col) ⇒ Boolean
(also: #dark?)
checked?is called with acolandrowparameter. -
#error_correction_level ⇒ Object
Return a symbol for current error connection level.
-
#initialize(data, *args) ⇒ QRCode
constructor
Expects a string or array (for multi-segment encoding) to be parsed in, other args are optional.
-
#inspect ⇒ Object
Public overide as default inspect is very verbose.
-
#mode ⇒ Object
Return a symbol in QRMODE.keys for current mode used.
-
#multi_segment? ⇒ Boolean
Return true if this QR Code includes multiple encoded segments.
-
#to_s(*args) ⇒ Object
This is a public method that returns the QR Code you have generated as a string.
Constructor Details
#initialize(data, *args) ⇒ QRCode
Expects a string or array (for multi-segment encoding) to be parsed in, other args are optional
# data - the string, QRSegment or array of Hashes (with data:, mode: keys) you wish to encode
# size - the size (Integer) of the QR Code (defaults to smallest size needed to encode the data)
# max_size - the max_size (Integer) of the QR Code (default RQRCodeCore::QRUtil.max_size)
# level - the error correction level, can be:
* Level :l 7% of code can be restored
* Level :m 15% of code can be restored
* Level :q 25% of code can be restored
* Level :h 30% of code can be restored (default :h)
# mode - the mode of the QR Code (defaults to alphanumeric or byte_8bit, depending on the input data, only used when data is a string):
* :number
* :alphanumeric
* :byte_8bit
qr = RQRCodeCore::QRCode.new('hello world', size: 1, level: :m, mode: :alphanumeric)
segment_qr = QRCodeCore::QRCode.new({ data: 'foo', mode: :byte_8bit })
multi_qr = RQRCodeCore::QRCode.new([{ data: 'foo', mode: :byte_8bit }, { data: 'bar1', mode: :alphanumeric }])
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 105 def initialize(data, *args) = (args) level = ([:level] || :h).to_sym max_size = [:max_size] || QRUtil.max_size @data = case data when String QRSegment.new(data: data, mode: [:mode]) when Array raise QRCodeArgumentError, "Array must contain Hashes with :data and :mode keys" unless data.all? { |seg| seg.is_a?(Hash) && i[data mode].all? { |s| seg.key? s } } data.map { |seg| QRSegment.new(**seg) } when QRSegment data else raise QRCodeArgumentError, "data must be a String, QRSegment, or an Array" end @error_correct_level = QRERRORCORRECTLEVEL[level] unless @error_correct_level raise QRCodeArgumentError, "Unknown error correction level `#{level.inspect}`" end size = [:size] || minimum_version(limit: max_size) if size > max_size raise QRCodeArgumentError, "Given size greater than maximum possible size of #{QRUtil.max_size}" end @version = size @module_count = @version * 4 + QRPOSITIONPATTERNLENGTH @modules = Array.new(@module_count) @data_list = multi_segment? ? QRMulti.new(@data) : @data.writer @data_cache = nil make end |
Instance Attribute Details
#module_count ⇒ Object (readonly)
Returns the value of attribute module_count.
84 85 86 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 84 def module_count @module_count end |
#modules ⇒ Object (readonly)
Returns the value of attribute modules.
84 85 86 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 84 def modules @modules end |
#version ⇒ Object (readonly)
Returns the value of attribute version.
84 85 86 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 84 def version @version end |
Class Method Details
.count_max_data_bits(rs_blocks) ⇒ Object
:nodoc:
423 424 425 426 427 428 429 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 423 def count_max_data_bits(rs_blocks) # :nodoc: max_data_bytes = rs_blocks.reduce(0) do |sum, rs_block| sum + rs_block.data_count end max_data_bytes * 8 end |
.create_bytes(buffer, rs_blocks) ⇒ Object
:nodoc:
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 448 def create_bytes(buffer, rs_blocks) # :nodoc: offset = 0 max_dc_count = 0 max_ec_count = 0 dcdata = Array.new(rs_blocks.size) ecdata = Array.new(rs_blocks.size) rs_blocks.each_with_index do |rs_block, r| dc_count = rs_block.data_count ec_count = rs_block.total_count - dc_count max_dc_count = [max_dc_count, dc_count].max max_ec_count = [max_ec_count, ec_count].max dcdata_block = Array.new(dc_count) dcdata_block.size.times do |i| dcdata_block[i] = 0xff & buffer.buffer[i + offset] end dcdata[r] = dcdata_block offset += dc_count rs_poly = QRUtil.get_error_correct_polynomial(ec_count) raw_poly = QRPolynomial.new(dcdata[r], rs_poly.get_length - 1) mod_poly = raw_poly.mod(rs_poly) ecdata_block = Array.new(rs_poly.get_length - 1) ecdata_block.size.times do |i| mod_index = i + mod_poly.get_length - ecdata_block.size ecdata_block[i] = (mod_index >= 0) ? mod_poly.get(mod_index) : 0 end ecdata[r] = ecdata_block end total_code_count = rs_blocks.reduce(0) do |sum, rs_block| sum + rs_block.total_count end data = Array.new(total_code_count) index = 0 max_dc_count.times do |i| rs_blocks.size.times do |r| if i < dcdata[r].size data[index] = dcdata[r][i] index += 1 end end end max_ec_count.times do |i| rs_blocks.size.times do |r| if i < ecdata[r].size data[index] = ecdata[r][i] index += 1 end end end data end |
.create_data(version, error_correct_level, data_list) ⇒ Object
:nodoc:
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 431 def create_data(version, error_correct_level, data_list) # :nodoc: rs_blocks = QRRSBlock.get_rs_blocks(version, error_correct_level) max_data_bits = QRCode.count_max_data_bits(rs_blocks) buffer = QRBitBuffer.new(version) data_list.write(buffer) buffer.(max_data_bits) if buffer.get_length_in_bits > max_data_bits raise QRCodeRunTimeError, "code length overflow. (#{buffer.get_length_in_bits}>#{max_data_bits}). (Try a larger size!)" end buffer.pad_until(max_data_bits) QRCode.create_bytes(buffer, rs_blocks) end |
Instance Method Details
#checked?(row, col) ⇒ Boolean Also known as: dark?
checked? is called with a col and row parameter. This will return true or false based on whether that coordinate exists in the matrix returned. It would normally be called while iterating through modules. A simple example would be:
instance.checked?( 10, 10 ) => true
150 151 152 153 154 155 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 150 def checked?(row, col) if !row.between?(0, @module_count - 1) || !col.between?(0, @module_count - 1) raise QRCodeRunTimeError, "Invalid row/column pair: #{row}, #{col}" end @modules[row][col] end |
#error_correction_level ⇒ Object
Return a symbol for current error connection level
212 213 214 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 212 def error_correction_level QRERRORCORRECTLEVEL.invert[@error_correct_level] end |
#inspect ⇒ Object
Public overide as default inspect is very verbose
RQRCodeCore::QRCode.new('my string to generate', size: 4, level: :h)
=> QRCodeCore: @data='my string to generate', @error_correct_level=2, @version=4, @module_count=33
207 208 209 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 207 def inspect "QRCodeCore: @data='#{@data}', @error_correct_level=#{@error_correct_level}, @version=#{@version}, @module_count=#{@module_count}" end |
#mode ⇒ Object
Return a symbol in QRMODE.keys for current mode used
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 222 def mode case @data_list when QRNumeric :mode_number when QRAlphanumeric :mode_alpha_numk else :mode_8bit_byte end end |
#multi_segment? ⇒ Boolean
Return true if this QR Code includes multiple encoded segments
217 218 219 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 217 def multi_segment? @data.is_a?(Array) end |
#to_s(*args) ⇒ Object
This is a public method that returns the QR Code you have generated as a string. It will not be able to be read in this format by a QR Code reader, but will give you an idea if the final outout. It takes two optional args :dark and :light which are there for you to choose how the output looks. Here’s an example of it’s use:
instance.to_s =>
xxxxxxx x x x x x xx xxxxxxx
x x xxx xxxxxx xxx x x
x xxx x xxxxx x xx x xxx x
instance.to_s( dark: 'E', light: 'Q' ) =>
EEEEEEEQEQQEQEQQQEQEQQEEQQEEEEEEE
EQQQQQEQQEEEQQEEEEEEQEEEQQEQQQQQE
EQEEEQEQQEEEEEQEQQQQQQQEEQEQEEEQE
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/rqrcode_core/qrcode/qr_code.rb', line 178 def to_s(*args) = (args) dark = [:dark] || "x" light = [:light] || " " quiet_zone_size = [:quiet_zone_size] || 0 rows = [] @modules.each do |row| cols = light * quiet_zone_size row.each do |col| cols += (col ? dark : light) end rows << cols end quiet_zone_size.times do rows.unshift(light * (rows.first.length / light.size)) rows << light * (rows.first.length / light.size) end rows.join("\n") end |