Generating a Code39 Barcode: Difference between revisions
Line 13: | Line 13: | ||
# Based on postnet2.py originally 2006.03.06 Gregory Pittman | # Based on postnet2.py originally 2006.03.06 Gregory Pittman | ||
# this version 2010.08.01 | # this version 2010.08.01 | ||
# | # encodes numbers and letters, plus the start/stop character | ||
""" | """ | ||
Simple operation. | Simple operation. | ||
First dialog asks for your code (numbers | First dialog asks for your code (numbers and uppercase letters), | ||
as you want. | as many characters as you want. | ||
Second dialog asks for height of bars in points. Barcode is arbitrarily | Second dialog asks for height of bars in points. Barcode is arbitrarily | ||
created at X-Pos of 200, Y-Pos 100. (the relx, rely values) | created at X-Pos of 200, Y-Pos 100. (the relx, rely values) | ||
Line 26: | Line 26: | ||
import scribus | import scribus | ||
# first the codes for numbers 0-9 | |||
# | code39n = ['nnswwn','wnsnnw','nwsnnw','wwsnnn','nnswnw','wnswnn','nwswnn','nnsnww','wnsnwn','nwsnwn'] | ||
# | # next add the codes for A-Z | ||
code39a = ['wnnsnw','nwnsnw','wwnsnn','nnwsnw','wnwsnn','nwwsnn','nnnsww','wnnswn','nwnswn'] | |||
code39b = ['nnwswn','wnnnsw','nwnnsw','wwnnsn','nnwnsw','wnwnsn','nwwnsn','nnnwsw','wnnwsn'] | |||
code39c = ['nwnwsn','nnwwsn','wsnnnw','nswnnw','wswnnn','nsnwnw','wsnwnn','nswwnn'] | |||
# doing this since I couldn't get list.extend to work | |||
code39 = code39n + code39a + code39b + code39c | |||
startstop = 'nsnwwn' | startstop = 'nsnwwn' | ||
narrow = 1.0 # narrow line | narrow = 1.0 # narrow line width | ||
wide = 2.2 # wide line | wide = 2.2 # wide line width | ||
b="Black" #line color | b="Black" #line color | ||
relx=200 #Start X | relx=200 #Start X | ||
Line 38: | Line 43: | ||
if scribus.haveDoc(): | if scribus.haveDoc(): | ||
S = scribus.valueDialog('Code 39','Enter | S = scribus.valueDialog('Code 39','Enter Numbers or Uppercase Letters') | ||
height = scribus.valueDialog('Code 39','Enter Height of Bars (Points)') | height = scribus.valueDialog('Code 39','Enter Height of Bars (Points)') | ||
height = int(height) | height = int(height) | ||
Line 44: | Line 49: | ||
scribus.setUnit(0) | scribus.setUnit(0) | ||
code = startstop | code = startstop | ||
for x in S[0:]: | for x in S[0:]: | ||
Line 50: | Line 55: | ||
xnum = int(x) | xnum = int(x) | ||
code = code + code39[xnum] | code = code + code39[xnum] | ||
elif ((ord(x) > 64) and (ord(x) < 91)): # ord(character) yields the ascii value | |||
xnum = ord(x) - 55 | |||
code = code + code39[xnum] | |||
code = code + startstop | code = code + startstop | ||
for y in code[0:]: | for y in code[0:]: | ||
if y == 'n': | if y == 'n': | ||
relx = relx + narrow/2 | relx = relx + narrow/2 |
Revision as of 02:53, 2 August 2010
The reason for writing this script was that I had already written a script for modifying a form we use, and on this form are barcodes, one of which indicates the type of form, but the other is variable according to the content of the page.
The script creates that custom part, which has a 10-digit number, then underneath is the barcode. By trial and error I determined that this was a Code39 barcode. Unfortunately, the barcode generator in Scribus cannot be scripted, and in fact you cannot make a custom size for the barcode, so I was copying the 10-digit number, then running Barcode generator, then resizing the created code, which is a PostScript creation, so when it's resized, the width of the bars may change. So far it's been Ok, but this might affect the scanning process.
So here is a first attempt, code39.py. I had thought it was rather slow, but rechecking shows acceptable speed on various computers. So far this will only generate a code for digits (plus the start/stop characters). Will add letter capability when I get a chance.
code39.py
#!/usr/bin/env python # -*- coding: utf-8 -*- # File: code39.py # Based on postnet2.py originally 2006.03.06 Gregory Pittman # this version 2010.08.01 # encodes numbers and letters, plus the start/stop character """ Simple operation. First dialog asks for your code (numbers and uppercase letters), as many characters as you want. Second dialog asks for height of bars in points. Barcode is arbitrarily created at X-Pos of 200, Y-Pos 100. (the relx, rely values) """ import scribus # first the codes for numbers 0-9 code39n = ['nnswwn','wnsnnw','nwsnnw','wwsnnn','nnswnw','wnswnn','nwswnn','nnsnww','wnsnwn','nwsnwn'] # next add the codes for A-Z code39a = ['wnnsnw','nwnsnw','wwnsnn','nnwsnw','wnwsnn','nwwsnn','nnnsww','wnnswn','nwnswn'] code39b = ['nnwswn','wnnnsw','nwnnsw','wwnnsn','nnwnsw','wnwnsn','nwwnsn','nnnwsw','wnnwsn'] code39c = ['nwnwsn','nnwwsn','wsnnnw','nswnnw','wswnnn','nsnwnw','wsnwnn','nswwnn'] # doing this since I couldn't get list.extend to work code39 = code39n + code39a + code39b + code39c startstop = 'nsnwwn' narrow = 1.0 # narrow line width wide = 2.2 # wide line width b="Black" #line color relx=200 #Start X rely=100 #Start Y if scribus.haveDoc(): S = scribus.valueDialog('Code 39','Enter Numbers or Uppercase Letters') height = scribus.valueDialog('Code 39','Enter Height of Bars (Points)') height = int(height) scribus.setRedraw(1) scribus.setUnit(0) code = startstop for x in S[0:]: if x.isdigit(): xnum = int(x) code = code + code39[xnum] elif ((ord(x) > 64) and (ord(x) < 91)): # ord(character) yields the ascii value xnum = ord(x) - 55 code = code + code39[xnum] code = code + startstop for y in code[0:]: if y == 'n': relx = relx + narrow/2 d = scribus.createLine(relx,rely,relx,rely + height,) #narrow line scribus.setLineWidth(narrow, d) scribus.setLineColor(b, d) scribus.setFillColor(b, d) relx = relx + narrow + narrow/2 elif y == 'w': relx = relx + wide/2 d = scribus.createLine(relx,rely,relx,rely + height,) #wide line scribus.setLineWidth(wide, d) scribus.setLineColor(b, d) scribus.setFillColor(b, d) relx = relx + narrow + wide/2 elif y == 's': #for wide space relx = relx + wide scribus.redrawAll()
Line Positions
Something worth mentioning here is that the precise position of the endpoints of lines is in the middle of the line. Thus, when I was creating lines of a particular width with very specific spacing in between, I had to account for the width of the lines or otherwise they would encroach on the space, and so you see these weird arithmetic additions in the if/elif loops.
About Code39
Code 39 is a widely used code consisting of a series of narrow and wide black lines, alternating with narrow or wide white spaces. Each character is denoted by a sequence of 5 lines and 4 intervening spaces, with a narrow space in between characters. The digits 0-9 and capital letters A-Z, plus *, hyphen, period, $, /, % and space are defined. The * character is also known as the start/stop character, since all codes should begin and end with it to orient the scanner.
Narrow and wide lines, and narrow and wide spaces have corresponding width values, and the relative ratios are generally 1:2.2 to 1:3 (narrow:wide).