Class: PDF417

Inherits:
Object
  • Object
show all
Defined in:
lib/pdf417.rb

Defined Under Namespace

Classes: GenerationError, Lib

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*attrs) ⇒ PDF417

Returns a new instance of PDF417.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/pdf417.rb', line 16

def initialize(*attrs)
  # TODO:  Test these defaults, make sure that they can get set on init, check to see that the output changes accordingly
  self.text = ""
  @y_height = 3
  @aspect_ratio = 0.5
  @rows = 1
  @cols = 0
  
  if attrs.first.is_a?(String)
    self.text = attrs.first
  elsif attrs.first.is_a?(Hash)      
    attrs.first.each do |k,v|
      if self.respond_to?("#{k}=".to_sym)
        self.send("#{k}=".to_sym, v)
      end
    end
  end

  @blob = nil
end

Instance Attribute Details

#bit_columnsObject (readonly)

Returns the value of attribute bit_columns.



14
15
16
# File 'lib/pdf417.rb', line 14

def bit_columns
  @bit_columns
end

#bit_lengthObject (readonly)

Returns the value of attribute bit_length.



14
15
16
# File 'lib/pdf417.rb', line 14

def bit_length
  @bit_length
end

#bit_rowsObject (readonly)

Returns the value of attribute bit_rows.



14
15
16
# File 'lib/pdf417.rb', line 14

def bit_rows
  @bit_rows
end

Class Method Details

.encode_text(text) ⇒ Object



9
10
11
# File 'lib/pdf417.rb', line 9

def encode_text(text)
  PDF417::Lib.encode_text(text)
end

Instance Method Details

#aspect_ratioObject

Aspect ratio



70
71
72
# File 'lib/pdf417.rb', line 70

def aspect_ratio
  @aspect_ratio
end

#aspect_ratio=(val) ⇒ Object



73
74
75
76
# File 'lib/pdf417.rb', line 73

def aspect_ratio=(val)
  @blob = nil
  @aspect_ratio = val
end

#codewordsObject



55
56
57
58
# File 'lib/pdf417.rb', line 55

def codewords
  return @raw_codewords if !@raw_codewords.nil?
  @codewords ||= self.class.encode_text(text)
end

#colsObject

Make the barcode at least this number of columns



97
98
99
# File 'lib/pdf417.rb', line 97

def cols
  @cols
end

#cols=(val) ⇒ Object



100
101
102
103
# File 'lib/pdf417.rb', line 100

def cols=(val)
  @blob = nil
  @cols = val
end

#encodingObject



183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/pdf417.rb', line 183

def encoding
  self.generate! if @blob.nil?
  
  # This matches the output from the pdf417 lib sample output.
  enc = self.blob.bytes.to_a.each_slice(self.bit_rows).to_a[0..(self.rows-1)] # sometimes we get more rows than expected, truncate
  
  # The length returned here is too long and we have extra data that gets padded w/ zeroes, meaning it doesn't all match.
  # Eg, instead of ending with "111111101000101001" it ends with "1111111010001010010000000".
  return enc.collect do |row_of_bytes|
    row_of_bytes.collect{|x| sprintf("%08b", x)}.join[0..self.bit_columns-1]
  end
end

#encoding_to_sObject



196
197
198
# File 'lib/pdf417.rb', line 196

def encoding_to_s
  self.encoding.each{|x| puts x.gsub("0"," ")}
end

#error_levelObject

Request the specified error level must be between 0 and 8



106
107
108
# File 'lib/pdf417.rb', line 106

def error_level
  @error_level
end

#error_level=(val) ⇒ Object



109
110
111
112
# File 'lib/pdf417.rb', line 109

def error_level=(val)
  @blob = nil
  @error_level = val
end

#generate!Object



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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/pdf417.rb', line 114

def generate!
  lib = Lib.new(text)
  options = []
  # Setting the text via accessor will set the codewords to nil, but if they have
  # been manually set pass them on.
  if @raw_codewords.is_a?(Array)
    lib.raw_codewords = @raw_codewords
    lib.generation_options |= Lib::PDF417_USE_RAW_CODEWORDS
    options << 'raw codewords'
  end
  
  if self.rows.to_i > 0 && self.cols.to_i > 0
    lib.code_rows = self.rows.to_i
    lib.code_cols = self.cols.to_i
    lib.generation_options |= Lib::PDF417_FIXED_RECTANGLE
    options << "#{rows}x#{cols}"
  elsif self.rows.to_i > 0
    lib.code_rows = self.rows.to_i 
    lib.generation_options |= Lib::PDF417_FIXED_ROWS
    options << "#{rows} rows"
  elsif self.cols.to_i > 0
    lib.code_cols = self.cols.to_i
    lib.generation_options |= Lib::PDF417_FIXED_COLUMNS
    options << "#{cols} cols"
  end

  if self.error_level.to_i >= 0 && self.error_level.to_i <= 8
    lib.error_level = self.error_level.to_i
    lib.generation_options |= Lib::PDF417_USE_ERROR_LEVEL
    options << "requested #{error_level.to_i} error level"
  end

  lib.aspect_ratio = self.aspect_ratio.to_f
  lib.y_height = self.y_height.to_f

  (@blob = lib.to_blob) 
  if @blob.nil? || @blob.empty?
    if lib.generation_error == Lib::PDF417_ERROR_TEXT_TOO_BIG
      raise GenerationError, "Text is too big"
    elsif lib.generation_error == Lib::PDF417_ERROR_INVALID_PARAMS
      msg = "Invalid parameters: #{options.join(', ')}"
      if lib.generation_options & Lib::PDF417_USE_RAW_CODEWORDS && lib.raw_codewords.length != lib.raw_codewords.first
        msg +=".  The first element of the raw codwords must be the length of the array.  Currently it is #{lib.raw_codewords.first}, perhaps it should be #{lib.raw_codewords.length}?"
      end
      raise GenerationError, msg
    else
      raise GenerationError, "Could not generate bitmap error: #{options.join(', ')}"
    end
  else
    @codewords = lib.codewords
    @bit_columns = lib.bit_columns
    @bit_rows = ((lib.bit_columns - 1) / 8) + 1
    @bit_length = lib.bit_length
    @rows = lib.code_rows 
    @cols = lib.code_cols
    @error_level = lib.error_level
    @aspect_ratio = lib.aspect_ratio
    @y_height = lib.y_height
    return true
  end
end

#inspectObject



37
38
39
# File 'lib/pdf417.rb', line 37

def inspect
  "#<#{self.class.name}:#{self.object_id} >"
end

#raw_codewordsObject

For setting the codewords directly



79
80
81
# File 'lib/pdf417.rb', line 79

def raw_codewords
  @raw_codewords
end

#raw_codewords=(val) ⇒ Object



82
83
84
85
# File 'lib/pdf417.rb', line 82

def raw_codewords=(val)
  @blob = nil
  @raw_codewords = val
end

#rowsObject

Make the barcode at least this number of rows



88
89
90
# File 'lib/pdf417.rb', line 88

def rows
  @rows
end

#rows=(val) ⇒ Object



91
92
93
94
# File 'lib/pdf417.rb', line 91

def rows=(val)
  @blob = nil
  @rows = val
end

#textObject



47
48
49
50
51
52
53
# File 'lib/pdf417.rb', line 47

def text
  if @raw_codewords.nil?
    @text
  else
    ""
  end
end

#text=(val) ⇒ Object



42
43
44
45
# File 'lib/pdf417.rb', line 42

def text=(val)
  @codewords = @blob = nil
  @text = val
end

#to_blobObject Also known as: blob



177
178
179
180
# File 'lib/pdf417.rb', line 177

def to_blob
  self.generate! if @blob.nil?
  @blob    
end

#to_png(opts = {}) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/pdf417.rb', line 200

def to_png(opts = {})
  require 'chunky_png' unless defined?(ChunkyPNG)
  
  self.generate! if @blob.nil?
  opts[:x_scale] ||= 1
  opts[:y_scale] ||= 3
  opts[:margin] ||= 10
  full_width = (self.bit_columns * opts[:x_scale]) + (opts[:margin] * 2)
  full_height = (self.rows * opts[:y_scale]) + (opts[:margin] * 2)
  
  canvas = ChunkyPNG::Image.new(full_width, full_height, ChunkyPNG::Color::WHITE)

  x, y = opts[:margin], opts[:margin]
  booleans = encoding.map{|l| l.split(//).map{|c| c == '1' } }
  booleans.each do |line|
    line.each do |bar|
      if bar
        x.upto(x+(opts[:x_scale]-1)) do |xx|
          y.upto y+(opts[:y_scale]-1) do |yy|
            canvas[xx,yy] = ChunkyPNG::Color::BLACK
          end
        end
      end
      x += opts[:x_scale]
    end
    y += opts[:y_scale]
    x = opts[:margin]
  end
  canvas.to_datastream.to_s    
end

#y_heightObject

Y Height



61
62
63
# File 'lib/pdf417.rb', line 61

def y_height
  @y_height
end

#y_height=(val) ⇒ Object



64
65
66
67
# File 'lib/pdf417.rb', line 64

def y_height=(val)
  @blob = nil
  @y_height = val
end