Skip to content

Instantly share code, notes, and snippets.

@goreilly
Created August 30, 2017 18:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goreilly/b53f1fcd9e68ebaac007cd6bb71359d5 to your computer and use it in GitHub Desktop.
Save goreilly/b53f1fcd9e68ebaac007cd6bb71359d5 to your computer and use it in GitHub Desktop.
def code128spec(string)
lookup = %w(
\ ! " # $ % & ' ( ) * + , - . /
0 1 2 3 4 5 6 7 8 9
: ; < = > ? @
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
[ \\ ] ^ _ `
a b c d e f g h i j k l m n o p q r s t u v w x y z
{ | } ~ )
patterns = %w(
11011001100 11001101100 11001100110 10010011000 10010001100 10001001100 10011001000 10011000100 10001100100 11001001000
11001000100 11000100100 10110011100 10011011100 10011001110 10111001100 10011101100 10011100110 11001110010 11001011100
11001001110 11011100100 11001110100 11101101110 11101001100 11100101100 11100100110 11101100100 11100110100 11100110010
11011011000 11011000110 11000110110 10100011000 10001011000 10001000110 10110001000 10001101000 10001100010 11010001000
11000101000 11000100010 10110111000 10110001110 10001101110 10111011000 10111000110 10001110110 11101110110 11010001110
11000101110 11011101000 11011100010 11011101110 11101011000 11101000110 11100010110 11101101000 11101100010 11100011010
11101111010 11001000010 11110001010 10100110000 10100001100 10010110000 10010000110 10000101100 10000100110 10110010000
10110000100 10011010000 10011000010 10000110100 10000110010 11000010010 11001010000 11110111010 11000010100 10001111010
10100111100 10010111100 10010011110 10111100100 10011110100 10011110010 11110100100 11110010100 11110010010 11011011110
11011110110 11110110110 10101111000 10100011110 10001011110 10111101000 10111100010 11110101000 11110100010 10111011110
10111101110 11101011110 11110101110 11010000100 11010010000 11010011100 11000111010 11010111000 )
# Invalid characters are replaced with spaces
values = string.chars.map {|letter| lookup.index(letter) || 0}
start = 104
quiet = '0' * 10
final = '11'
stop = 106
checksum = values.each_with_index.reduce(start) {|sum, (d, i)| sum + d * (i + 1)} % 103
[quiet, *patterns.values_at(*[start, *values, checksum, stop]), final, quiet]
.join('')
.scan(/((\d)\2*)/) # Find consecutive sections
.map(&:first)
.map {|section| [section.length, section[0] == '1']}
end
def pngbarcode(data, filename, bar_width: 2, bar_height: 70)
require 'rmagick'
spec = code128spec(data)
image_width = spec.reduce(0) {|sum, (length, _)| sum + length * bar_width}
img = Magick::ImageList.new
draw = Magick::Draw.new
img.new_image image_width, bar_height
left = 0
spec.each do |(bars, black)|
width = bars * bar_width
draw.fill black ? 'black' : 'white'
draw.rectangle left, 0, left + width, bar_height
left += width
end
draw.draw(img)
img.write(filename)
end
pngbarcode('hello world', 'test.png')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment