Skip to content

Instantly share code, notes, and snippets.

@mikebaldry
Created February 21, 2018 10:13
Show Gist options
  • Save mikebaldry/ff58c7f881e716bbfe096840faf06d36 to your computer and use it in GitHub Desktop.
Save mikebaldry/ff58c7f881e716bbfe096840faf06d36 to your computer and use it in GitHub Desktop.
Barby::Outputter to generate "proper" EAN-13 barcodes, with guard lines and code written below
class EAN13Outputter < Barby::RmagickOutputter
attr_writer :font_size
def to_image(opts = {})
with_options opts do
canvas = Magick::Image.new(full_width, full_height)
bars = Magick::Draw.new
x1 = margin + offset_width
y1 = margin + (offset_height / 2)
guard_positions = []
booleans_with_guard.each do |(bar, guard)|
if bar
x2 = x1+(xdim-1)
y2 = y1+(height-1)
if guard.present?
y2 += guard_height
guard_positions << x1
end
bars.rectangle(x1, y1, x2, y2)
end
x1 += xdim
end
bars.draw(canvas)
draw_data(canvas, guard_positions)
canvas
end
end
def draw_data(canvas, guard_positions)
draw_data_part(canvas, barcode.to_s[0, 1], margin, margin * 2.5)
draw_data_part(canvas, barcode.to_s[1, 6], guard_positions[1], guard_positions[2])
draw_data_part(canvas, barcode.to_s[7, 6], guard_positions[3], guard_positions[4])
end
def draw_data_part(canvas, part, start_x, end_x)
text_width = text.get_type_metrics(part).width
available_width = end_x - start_x
centered_x = (available_width / 2) - (text_width / 2)
text.annotate(canvas, 0, 0, start_x + centered_x, offset_height, part)
end
def booleans_with_guard
raise "This doesn't look like an EAN-13 barcode" unless booleans.length == 95
guards = [
0, 2, # left guard
46, 48, # center guard
92, 94 # right guard
]
booleans.map.with_index do |boolean, index|
[boolean, guards.index(index).try(:+, 1)]
end
end
def text
@magick_text_draw ||= begin
result = Magick::Draw.new
result.font_family = 'arial'
result.pointsize = @font_size
result.gravity = Magick::SouthWestGravity
result
end
end
def font_size
@font_size || 22
end
def character_height
@character_height ||= text.get_type_metrics("M").height
end
def guard_height
height * 0.15
end
def offset_width
@offset_width ||= text.get_type_metrics("M").width
end
def offset_height
@offset_height ||= (character_height / 2)
end
def full_height
super + guard_height + (offset_height * 2)
end
def full_width
super + (offset_width * 2)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment