Bar Code generator

I had begun the initial prototyping of my own code to make scannable bar codes for inventory tracking, when I discovered the superb Zint library that does everything I needed. Hence, the following code is an interface to utilize the zint tcl library. It exposes the possible 1-D and 2-D bar code symbologies supported by zint, and allows for easy input of the alphanumeric data to encode, along with surrounding whitespace, height, and scaling. The bar code is displayed and automatically saved to PNG file for later print it to a label.

if 0 {
2023-02-06 FRANK BANNON
Uses [tzint+-+tcl+package+for+libzint+barcode+encoding+library+%28no+Tk+needed%29] package ( to generate bar code images, copied to folder under TCL /lib/

get list of possible bar code symbologies
        zint symbologies
create a typical bar code
        zint encode <data> <imagename> -barcode Code128 -height 20 -whitesp 20 -scale 1

foreach {pkg src} {
        zint ""
        Img ""
        } {
        if {[catch {package require $pkg} result]} {
                set msg "Package $pkg not loaded: $result"
                if {[string length $src]} {append msg "\nDownload from $src"}
                tk_messageBox -default ok -icon error -type ok \
                        -message $msg -title "Error loading $pkg TCL package"
                puts $msg

# parameters, some are set later
array set p {
        barcodes {Logmars Code128}
        barcode Logmars
        data        001436
        height        20
        whitespace 20
        scale        1
        fileformat        png

wm minsize . 150 150
# symbology of bar code to generate
. configure -menu .menu
menu .menu -cursor {}
set m .menu.code
        .menu add cascade -menu $m -label Symbology -underline 0
        menu $m -tearoff 0
        # all in one huge list
#        foreach b [lsort -dict [zint symbologies]] {
#                $m add radiobutton -variable p(barcode) -label $b -value $b
#        }
# create smaller submenus to avoid endless scrolling
set m2 $
foreach fam $nameGroups {
        $m add cascade -menu $m2$fam -label "$fam"
        menu $m2$fam -tearoff 0
# add each symbol type to a submenu
foreach f [lsort -dict [zint symbologies]] {
        # determine which grouping the name belongs
        set s [string toupper [string index $f 0]]
        foreach fg $nameGroups {
                if {[string first $s $fg] > -1} {break}
        $m2$fg add radiobutton -label $f -variable p(barcode) -value $f \
                -command make
unset nameGroups m m2 fam f s fg

# data for bar code
frame .f1
label .f1.data1 -text "Data: "
entry .f1.data2 -textvariable p(data) -font {-size 16 -weight bold}
        bind .f1.data2 <Key-Return> make
label .f1.code1 -text "Symbol: "
label .f1.code2 -textvariable p(barcode)
pack .f1.data1 .f1.data2 .f1.code1 .f1.code2 -side left
pack .f1 -anchor nw

# options
frame .f2
# Height range: 0.5 to 100
label .f2.height1 -text "Height: "
entry .f2.height2 -textvariable p(height) -width 6
        bind .f2.height2 <Key-Return> make
# Whitepsace range: 0 to 100, adds blank space around barcode
label .f2.space1 -text "Whitespace: "
entry .f2.space2 -textvariable p(whitespace) -width 6
        bind .f2.space2 <Key-Return> make
# Scale range: 1 to 20, affects pixel dimensions of output
label .f2.scale1 -text "Scale: "
entry .f2.scale2 -textvariable p(scale) -width 6
        bind .f2.scale2 <Key-Return> make
pack .f2.height1 .f2.height2 .f2.space1 .f2.space2 .f2.scale1 .f2.scale2 -side left
pack .f2 -anchor nw

# image of generated bar code, want to make this resize with window
set p(image) [image create photo ] ;# -width 600 -height 200
label .phot -anchor nw -image $p(image)
pack .phot -anchor nw -expand 1 -fill both

label .status -textvariable p(status)
pack .status -anchor nw

# create barcode using given data and symbology, no args passed in, data pulled from p array
proc make args {
        global p
        # erase previous bar code image
        $p(image) blank
        # generate bar code using zint API
        if {[catch {zint encode $p(data) $p(image) -barcode $p(barcode) -height $p(height) -whitesp $p(whitespace) -scale $p(scale)} result]} {
                # catch failure
                puts "\nFailed to make bar code $p(barcode) containing $p(data)"
                puts "$result\n"
                set p(status) $result
        # filename: data (symbology).format
        set filename "$p(data) ($p(barcode)).$p(fileformat)"
        # write output file
        catch {$p(image) write $filename -format $p(fileformat)} result
        # generated image dimensions
        set p(dimx) [image width $p(image)]
        set p(dimy) [image height $p(image)]
        set dim "($p(dimx) x $p(dimy) pixels)"
        if {[file exists $filename]} {set p(status) "Wrote $filename $dim"} else {set p(status) "Failed to write $filename: $result"}

catch {console show}