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. ---- [Jeff Smith] 2023-09-25 : Below is an online demo using [CloudTk]. This demo runs “Bar Code generator” in an Alpine Linux Docker container. It is a 28.6MB image which is made up of Alpine Linux + tclkit + Bar-Code-generator.kit + libx11 + libxft + fontconfig + ttf-linux-libertine. It is run under a user account in the container. The container is restrictive with permissions for "Other" removed for "execute" and "read" for certain directories. <> <> ---- ====== if 0 { BAR CODE GENERATOR 2023-02-06 FRANK BANNON Uses https://zint.org.uk%|%Zint 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 -barcode Code128 -height 20 -whitesp 20 -scale 1 } # REQUIRED TCL PACKAGES foreach {pkg src} { zint "https://zint.org.uk" 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 nameGroups {ABC DEF GHI JKL MNO PQR STU VWXYZ Misc} set m2 $m.group 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 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 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 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 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 return } # 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} ======