Friday, 14 September 2012

EAN-13 barcode generator

This is a useful script to see and print EAN-13 barcodes. If you don't know what is a EAN-13 barcode, look at: Wikipedia

You can use the image (r variable) to print it. See here  to print with rebol.
To use it just digit the gencode command and the 12 digits, the script will calculate the 13rd digit and show the barcode:


gencode "123456789012"


Here the source:

REBOL [
    Title:   "EAN-13 Barcode Image Generator"
    Library: [
        level: 'intermediate
        platform: 'all
        type: [tool]
        domain: [graphics]
        tested-under: none
        support: none
        license: none
        see-also: none  
    ]
    Date:     15-Mar-2005
    Version: 2.0.0
    File:     %ean13.r
    Home:     http://www.hmkdesign.dk/rebol/ean13.r
    Author:   ["Henrik Mikael Kristensen" "Massimiliano Vessi"]
    Owner:   "HMK Design"
    Rights:   "Copyright (C) HMK Design 2005"
    Purpose: {
        Generates EAN-13 barcode images as image! which can be used for
        print out and later read with a barcode reader.
        It's means to the the basic first version of a fuil barcode generator script
        for support of mulitple barcode types.
        Usage: gencode "123456789012"
        Any 12-digit can be used,
        to be read by a barcode reader.
        See '? gencode' for help on options
        Example: gencode "750103131130"
    }
    Note: {Feel free to edit/optimize, but please send revisions to me. Thanks!
    Max email is: maxint@tiscali.it
    }
    History: [
    0.1.0 [6-Mar-2005 "Prototype version." "Henrik"]
    2.0.0 [14-Sep-2012 "Added checksum digit and corrected the numbers positions" "Max"]
    ]
    Language: 'English
]
; generate EAN-13 barcodes

codes-left-odd: copy [
  "0001101" "0011001" "0010011" "0111101"
  "0100011" "0110001" "0101111" "0111011"
  "0110111" "0001011"
]
codes-left-even: copy [
  "0100111" "0110011" "0011011" "0100001"
  "0011101" "0111001" "0000101" "0010001"
  "0001001" "0010111"
]
; right codes are left odd codes reversed, so the right output is simply inverted

parity: copy [
  "111111" "110100" "110010" "110001"
  "101100" "100110" "100011" "101010"
  "101001" "100101"
]
ean13checksum: func [input_string /local total total2 temp][
    total: total2: 0
    for i 2 12 2 [
        total: (to-integer to-string input_string/:i) + total      
        ]
   
    total: total * 3
    for i 1 11 2 [total2: (to-integer to-string input_string/:i) + total2 ]
    total: total + total2
   
    for i 0 9 1[
        if   ((total + i) // 10 ) = 0 [ temp: i]    
        ]
    temp
    ]
to-int: funcinput][to-integer to-string input]
guard: copy [
  box guardbarsize black
  box guardbarsize
  box guardbarsize black
]
gencode: func [
  "Outputs a bitmapped EAN-13 barcode in a view window"
  input [string!] "Must be 12 digits"
  /big "Prints 2 times larger barcode."
  /bigger {Prints 4 times larger barcode.
          Combine with /big for 8 times larger barcode.}

][
  barsize: 1x50
  guardbarsize: 1x60
  spacesize: 1x0
  pos0: 11x0 ;bar position
  pos1: 0x50 ;numbers positions
  pos2: 12x50
  pos3: 58x50
  pos4: 105x50
  tfont: 12
  if big [
    barsize: barsize * 2
    guardbarsize: guardbarsize * 2
    spacesize: spacesize * 2
    pos0: pos0 * 2
    pos1: pos1 * 2
    pos2: pos2 * 2
    pos3: pos3 * 2
    pos4: pos4 * 2
    tfont: tfont * 2
  ]
  if bigger [
    barsize: barsize * 4
    guardbarsize: guardbarsize * 4
    spacesize: spacesize * 4
    pos0: pos0 * 4
    pos1: pos1 * 4
    pos2: pos2 * 4
    pos3: pos3 * 4
    pos4: pos4 * 4
    tfont: tfont * 4
  ]
  input: copy input
  either 12 == length? input [
  append input (ean13checksum input )
  t: copy compose [backdrop white space 0 origin (pos0) across]
  ; left guard
  append t guard
  ; left half
  parityidx: first skip parity to-int first input
  for i 2 7 1 [; digit
    digit: to-int input/:i
    ; read parityidx for this digit
    code: either odd? first at parityidx (i - 1) [
      first skip codes-left-odd digit
    ][first skip codes-left-even digit ] (i - 1)
    for j 1 7 1 [
      append t either zero? to-int code/:j [[box barsize]][[box barsize black]]
    ]
  ]
  ; center guard  
  append t [box guardbarsize]
  append t guard
  append t [box guardbarsize]
  ; right half
  for i 8 13 1 [; digit
    idx: 1 + to-int input/:i
    foreach code codes-left-odd/:idx [
      append t either zero? to-int code [[box barsize black]][[box barsize]]
    ]
  ]
  ; right guard
  append t guard
  ; generate image
  append t compose/deep [at (pos1) text (to-string input/1) font [size: (tfont)] ]
  input: next input
  append t compose/deep [at (pos2) text (to-string copy/part input 6) font [size: (tfont)] ]
  loop 6 [input: next input ]
  append t compose/deep [at (pos3) text (to-string input) font [size: (tfont)] ]
  append t compose/deep [at (pos4) text ">" font [size: (tfont)] ]
  input: head input ; if you need to use again
 
  r: to-image layout t ; you can use this image to print bar-code
  view layout [backdrop white text "EAN-13 BARCODE" image r button "Close" [unview]]
  ][print "Invalid code! not 12 digits..." ]
]
;examples:
;gencode "123456789012"
;gencode/big "123456789012"
;gencode/bigger "123456789012"


Using the refinements /big or  /bigger, you obtain bigger images.

1 comment:

  1. I've printed several million bar code labels in a commercial environment, using code39. This is a simplified version of the code I use - it outputs directly to PDF:

    http://www.rebol.org/view-script.r?script=pdf-barcode.r

    ReplyDelete