lib/img2zpl/image.rb in img2zpl-0.1.1 vs lib/img2zpl/image.rb in img2zpl-0.1.2
- old
+ new
@@ -1,32 +1,61 @@
class Img2Zpl::Image < MiniMagick::Image
- def to_zpl(black_threshold: 0.5)
+ def to_zpl(black_threshold: 0.5, compress: true)
bytes_per_row = (width % 8).positive? ? (width / 8) + 1 : (width / 8)
byte_count = bytes_per_row * height
data, line, previous_line, byte = '', '', '', ''
get_pixels.each do |row|
-
row.each_with_index do |column, i|
r, g, b = column.map(&:to_i)
byte << ((r + g + b) > (black_threshold * 765) ? '0' : '1')
if (i % 8).zero?
line << byte.to_i(2).to_s(16).upcase.rjust(2, '0')
byte = ''
end
end
- data << (line == previous_line ? ':' : line.gsub(/0+$/, ',').gsub(/F+$/, '!'))
+
+ data << if compress
+ (line == previous_line ? ':' : line.gsub(/0+$/, ',').gsub(/F+$/, '!'))
+ else
+ line
+ end
+
previous_line = line
line = ''
end
- "^FO0,0^GFA,#{byte_count},#{byte_count},#{bytes_per_row},#{data}^FS"
+ _compress(data) if compress
+ "^GFA,#{byte_count},#{byte_count},#{bytes_per_row},#{data}^FS"
end
private
def _compression_map
- # TODO: finish compression map
+ map = {}
+ start = 'G'.ord
+ 19.times { |i| map[i + 1] = (start+i).chr }
+ start = 'g'.ord
+ (20..400).step(20).each_with_index { |i, j| map[i] = (start+j).chr }
+ map
+ end
+
+ def _reduce(n)
+ str = ''
+ counts = _compression_map.keys.sort.reverse
+ counts.each do |c|
+ if c <= n
+ str << (_compression_map[c])
+ n -= c
+ end
+ end
+ str
+ end
+
+ def _compress(data)
+ data.gsub!(/([\da-zA-Z])(\1+)/) do |m|
+ "#{_reduce(m.length)}#{$1}"
+ end
end
end