[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r5963 - in trunk/gnue-common/src: . printing printing/barcodes
From: |
jcater |
Subject: |
r5963 - in trunk/gnue-common/src: . printing printing/barcodes |
Date: |
Sun, 11 Jul 2004 23:24:24 -0500 (CDT) |
Author: jcater
Date: 2004-07-11 23:24:23 -0500 (Sun, 11 Jul 2004)
New Revision: 5963
Added:
trunk/gnue-common/src/printing/
trunk/gnue-common/src/printing/__init__.py
trunk/gnue-common/src/printing/barcodes/
trunk/gnue-common/src/printing/barcodes/Base.py
trunk/gnue-common/src/printing/barcodes/README
trunk/gnue-common/src/printing/barcodes/__init__.py
trunk/gnue-common/src/printing/barcodes/codabar.py
trunk/gnue-common/src/printing/barcodes/code39.py
trunk/gnue-common/src/printing/barcodes/interleaved2of5.py
trunk/gnue-common/src/printing/barcodes/postnet.py
trunk/gnue-common/src/printing/barcodes/standard2of5.py
Log:
added my barcode library (still needs some verification)
Added: trunk/gnue-common/src/printing/__init__.py
===================================================================
Added: trunk/gnue-common/src/printing/barcodes/Base.py
===================================================================
--- trunk/gnue-common/src/printing/barcodes/Base.py 2004-07-11 17:35:14 UTC
(rev 5962)
+++ trunk/gnue-common/src/printing/barcodes/Base.py 2004-07-12 04:24:23 UTC
(rev 5963)
@@ -0,0 +1,130 @@
+import sys, os
+import Image, ImageDraw
+
+class InvalidBarcode(StandardError):
+ pass
+
+class Barcode:
+ mapping = {}
+ chars = []
+ validLengths = []
+ lineWidth = 1.44 # points (.02")
+ lineHeight = 18 # (.125")
+ spacing = ''
+ start = ''
+ stop = ''
+
+
+ def checkdigit(self, value):
+ """
+ Returns the checkdigit encoding for the given value
+ """
+ return ''
+
+ def calculateLineHeight(self, value, code):
+ return self.lineHeight
+
+ def _buildBinary(self, value):
+ """
+ Returns a string of 0s (no line) and 1s (line).
+ Note that, depending on the barcode type,
+ a single bar could be multiple
+ """
+
+ if self.validLengths and len(value) not in self.validLengths:
+ raise InvalidBarcode
+
+ value = str(value)
+ rv = self.start + self.spacing
+
+ first = True
+ for ch in value + self.checkdigit(value):
+ if first:
+ first = False
+ else:
+ rv += self.spacing
+ try:
+ rv += self.mapping[ch]
+ except KeyError:
+ raise InvalidBarcode
+
+ return rv + self.spacing + self.stop
+
+
+ ###
+ ###
+ ###
+ def generate(self, value, stream=sys.stdout,
+ format='postscript', dpi=300):
+
+ code = self._buildBinary(value)
+ lineWidth = self.lineWidth
+ lineHeight = self.calculateLineHeight(value, code)
+
+ ##
+ ## Vector-based PS/EPS output
+ ##
+ if format in ("postscript",'eps'):
+ # Special case for PostNet
+ lineHeight2 = self.lineHeight*.4
+
+ # Write minimal EPS header
+ if format == 'eps':
+ stream.write('%!PS-Adobe-3.0 EPSF-3.0\n')
+ stream.write('%%%%BoundingBox: 0 0 %s %s\n'% (
+ int(lineWidth*(len(code)+1)+.5),int(lineHeight+.5)))
+
+ # Initialize the graphics
+ stream.write('gsave\n0 setgray\n%s setlinewidth\nnewpath\n0 0 moveto\n'
% lineWidth)
+
+ # Draw each bar
+ for ch in code:
+ if ch == '1':
+ stream.write('0 %s rlineto %s -%s rmoveto\n' % (
+ lineHeight, lineWidth, lineHeight))
+
+ # Special case for PostNet as it is
+ # height-sensitive, not width-sensitive
+ elif ch == '2':
+ stream.write('0 %s rlineto %s -%s rmoveto\n' % (
+ lineHeight2, lineWidth, lineHeight2))
+
+ else:
+ stream.write('%s 0 rmoveto\n' % (
+ lineWidth))
+
+ # Do the actual drawing, and cleanup
+ stream.write('stroke\ngrestore\n')
+
+
+ ##
+ ## Raster-based output using PIL
+ ##
+ elif format in ('png','tiff','ppm','xbm'):
+ lineWidth = int(lineWidth * dpi/72+.5) # 300dpi
+ lineHeight = int(lineHeight * dpi/72+.5) # 300dpi
+ # Special case for PostNet
+ lineHeight2 = int(lineHeight * .4+.5)
+
+ # Create a new monochrome image with a white backgint
+ image = Image.new('1',(int(len(code)*lineWidth+.5),
+ int(lineHeight+.5)), 1)
+ draw = ImageDraw.Draw(image)
+ offs = 0
+ for ch in code:
+ if ch == '1':
+ draw.rectangle((offs,0,offs+lineWidth-1,lineHeight),
+ outline=0, fill=0)
+ # Special case for PostNet
+ elif ch == '2':
+ draw.rectangle((offs,0,offs+lineWidth-1,lineHeight2),
+ outline=0, fill=0)
+ offs += lineWidth
+
+ image.save(stream, format)
+
+
+ # Line height is .15 * barcode width, but at least .25"
+ # This is used by Code39, Interleaved 2 of 5, etc
+ def _calculate15(self, value, code):
+ return max(18, .15 * len(code) * self.lineWidth)
Added: trunk/gnue-common/src/printing/barcodes/README
===================================================================
--- trunk/gnue-common/src/printing/barcodes/README 2004-07-11 17:35:14 UTC
(rev 5962)
+++ trunk/gnue-common/src/printing/barcodes/README 2004-07-12 04:24:23 UTC
(rev 5963)
@@ -0,0 +1,9 @@
+
+Specs:
+ * http://www.adams1.com/pub/russadam/info.html#Specs
+ General line width specs, min sizes
+ (also has link to an online barcode generator to compare against)
+
+ * http://barcodeisland.com/symbolgy.phtml
+ A lot of encodings for barcodes, but no spacing specs
+
Added: trunk/gnue-common/src/printing/barcodes/__init__.py
===================================================================
Added: trunk/gnue-common/src/printing/barcodes/codabar.py
===================================================================
--- trunk/gnue-common/src/printing/barcodes/codabar.py 2004-07-11 17:35:14 UTC
(rev 5962)
+++ trunk/gnue-common/src/printing/barcodes/codabar.py 2004-07-12 04:24:23 UTC
(rev 5963)
@@ -0,0 +1,41 @@
+from Base import Barcode
+
+class Codabar(Barcode):
+ chars = '0123456789-$:/.+'
+ mapping = {
+ '0': '10101001100',
+ '1': '10101100100',
+ '2': '10100101100',
+ '3': '11001010100',
+ '4': '10110100100',
+ '5': '11010100100',
+ '6': '10010101100',
+ '7': '10010110100',
+ '8': '10011010100',
+ '9': '11010010100',
+ '-': '10100110100',
+ '$': '10110010100',
+ ':': '110101101100',
+ '/': '110110101100',
+ '.': '110110110100',
+ '+': '10110011001100'
+ }
+
+ start = '100100101100'
+ stop = '1010011001'
+
+ calculateLineHeight = Barcode._calculate15
+
+if __name__ == '__main__':
+
+ codabar = Codabar()
+
+ def test(value, format, file):
+ f = open(file,'wb')
+ codabar.generate(value,f, format)
+ f.close()
+
+ test('0123456789-$:/.+','png','test1.png')
+ test('+./:$-9876543210','tiff','test1.tif')
+ test('+./:$-9876543210','postscript','test1.ps')
+ test('0123456789-$:/.+','eps','test1.eps')
Added: trunk/gnue-common/src/printing/barcodes/code39.py
===================================================================
--- trunk/gnue-common/src/printing/barcodes/code39.py 2004-07-11 17:35:14 UTC
(rev 5962)
+++ trunk/gnue-common/src/printing/barcodes/code39.py 2004-07-12 04:24:23 UTC
(rev 5963)
@@ -0,0 +1,91 @@
+from Base import Barcode
+
+class Code39(Barcode):
+ """
+ Code 39 without a check digit
+ """
+ chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%'
+ mapping = {
+ '0': '1010011011010',
+ '1': '1101001010110',
+ '2': '1011001010110',
+ '3': '1101100101010',
+ '4': '1010011010110',
+ '5': '1101001101010',
+ '6': '1011001101010',
+ '7': '1010010110110',
+ '8': '1101001011010',
+ '9': '1011001011010',
+ 'A': '1101010010110',
+ 'B': '1011010010110',
+ 'C': '1101101001010',
+ 'D': '1010110010110',
+ 'E': '1101011001010',
+ 'F': '1011011001010',
+ 'G': '1010100110110',
+ 'H': '1101010011010',
+ 'I': '1011010011010',
+ 'J': '1010110011010',
+ 'K': '1101010100110',
+ 'L': '1011010100110',
+ 'M': '1101101010010',
+ 'N': '1010110100110',
+ 'O': '1101011010010',
+ 'P': '1011011010010',
+ 'Q': '1010101100110',
+ 'R': '1101010110010',
+ 'S': '1011010110010',
+ 'T': '1010110110010',
+ 'U': '1100101010110',
+ 'V': '1001101010110',
+ 'W': '1100110101010',
+ 'X': '1001011010110',
+ 'Y': '1100101101010',
+ 'Z': '1001101101010',
+ '-': '1001010110110',
+ '.': '1100101011010',
+ ' ': '1001101011010',
+ '$': '1001001010010',
+ '/': '1001001010010',
+ '+': '1001010010010',
+ '%': '1010010010010',
+ }
+
+ start= '1001011011010'
+ stop = '100101101101'
+
+ lineWidth = .72 # points (1.0mil)
+ lineHeight = 18 # Actually dependent on the width
+
+ calculateLineHeight = Barcode._calculate15
+
+
+######################################
+##
+##
+class Code39CheckDigit(Code39):
+ """
+ Code 39 with a Mod 43 check digit
+ """
+
+ # Calculate a Mod-43 check digit
+ def checkdigit(self, value):
+ v = 0
+ for ch in value:
+ v += self.chars.index(ch)
+ return self.mapping[self.chars[divmod(chv,43)[1]]]
+
+
+if __name__ == '__main__':
+
+ code39 = Code39()
+
+ def test(value, format, file):
+ f = open(file,'wb')
+ code39.generate(value,f, format)
+ f.close()
+
+ test('0123456789ABCDEF','png','test1.png')
+ test('0123456789ABCDEF','tiff','test1.tif')
+ test('0123456789','postscript','test1.ps')
+ test('0123456789ABCDEF','eps','test1.eps')
Added: trunk/gnue-common/src/printing/barcodes/interleaved2of5.py
===================================================================
--- trunk/gnue-common/src/printing/barcodes/interleaved2of5.py 2004-07-11
17:35:14 UTC (rev 5962)
+++ trunk/gnue-common/src/printing/barcodes/interleaved2of5.py 2004-07-12
04:24:23 UTC (rev 5963)
@@ -0,0 +1,77 @@
+from Base import Barcode
+
+class Interleaved2of5(Barcode):
+ chars = '0123456789'
+
+ # Interleaved works differently than the others
+ mapping = {
+ '0': 'NNWWN',
+ '1': 'WNNNW',
+ '2': 'NWNNW',
+ '3': 'WWNNN',
+ '4': 'NNWNW',
+ '5': 'WNWNN',
+ '6': 'NWWNN',
+ '7': 'NNNWW',
+ '8': 'WNNWN',
+ '9': 'NWNWN'
+ }
+
+ lineWidth = .54 # points (7.5mil)
+ lineHeight = 18 # Actually dependent on the width
+
+ start = '1010'
+ stop = '1101'
+
+ calculateLineHeight = Barcode._calculate15
+
+ # Since this is interleaved, we do
+ # our own custom buildBinary.
+ def _buildBinary(self, value):
+ """
+ Returns a string of 0s (no line) and 1s (line).
+ Note that, depending on the barcode type,
+ a single bar could be multiple
+ """
+
+ value = str(value)
+ if len(value)/2.0 != int(len(value)/2.0):
+ raise InvalidBarcode, \
+ 'Interleaved 2of5 must have an even number of digits'
+
+ rv = self.start
+
+ even = False
+ for i in range(len(value)/2):
+ try:
+ bar = self.mapping[value[i]]
+ space = self.mapping[value[i+1]]
+ except KeyError:
+ raise InvalidBarcode
+
+ for j in xrange(5):
+ if bar[j] == 'W':
+ rv += '11'
+ else:
+ rv += '1'
+ if space[j] == 'W':
+ rv += '00'
+ else:
+ rv += '0'
+
+ return rv + self.stop
+
+
+if __name__ == '__main__':
+
+ testbar = Interleaved2of5()
+
+ def test(value, format, file):
+ f = open(file,'wb')
+ testbar.generate(value,f, format)
+ f.close()
+
+ test('0123456789','png','test1.png')
+ test('9876543210','tiff','test1.tif')
+ test('9876543210','postscript','test1.ps')
+ test('0123456789','eps','test1.eps')
Added: trunk/gnue-common/src/printing/barcodes/postnet.py
===================================================================
--- trunk/gnue-common/src/printing/barcodes/postnet.py 2004-07-11 17:35:14 UTC
(rev 5962)
+++ trunk/gnue-common/src/printing/barcodes/postnet.py 2004-07-12 04:24:23 UTC
(rev 5963)
@@ -0,0 +1,51 @@
+from Base import Barcode, InvalidBarcode
+
+class PostNet(Barcode):
+ """
+ PostNet
+ """
+ validLengths = [5,9,11]
+ chars = '0123456789'
+ mapping = {
+ '0': '1010202020',
+ '1': '2020201010',
+ '2': '2020102010',
+ '3': '2020101020',
+ '4': '2010202010',
+ '5': '2010201020',
+ '6': '2010102020',
+ '7': '1020202010',
+ '8': '1020201020',
+ '9': '1020102020'
+ }
+
+ start = '10'
+ stop = '1'
+
+ lineWidth = 1.44 # points (.02")
+ lineHeight = 9 # (.125")
+
+ # Calculate a Mod-10 check digit
+ def checkdigit(self, value):
+ v = 0
+ for ch in value:
+ try:
+ v += int(ch)
+ except ValueError:
+ raise InvalidBarcode
+ return self.mapping[self.chars[divmod(v,10)[1]]]
+
+
+if __name__ == '__main__':
+
+ postnet = PostNet()
+
+ def test(value, format, file):
+ f = open(file,'wb')
+ postnet.generate(value,f, format)
+ f.close()
+
+ test('381072456','png','test1.png')
+ test('381172459','tiff','test1.tif')
+ test('381072456','postscript','test1.ps')
+ test('381072456','eps','test1.eps')
Added: trunk/gnue-common/src/printing/barcodes/standard2of5.py
===================================================================
--- trunk/gnue-common/src/printing/barcodes/standard2of5.py 2004-07-11
17:35:14 UTC (rev 5962)
+++ trunk/gnue-common/src/printing/barcodes/standard2of5.py 2004-07-12
04:24:23 UTC (rev 5963)
@@ -0,0 +1,36 @@
+from Base import Barcode
+
+class Standard2of5(Barcode):
+ chars = '0123456789'
+ mapping = {
+ '0': '10101110111010',
+ '1': '11101010101110',
+ '2': '10111010101110',
+ '3': '11101110101010',
+ '4': '10101110101110',
+ '5': '11101011101010',
+ '6': '10111011101010',
+ '7': '10101011101110',
+ '8': '11101010111010',
+ '9': '10111010111010'
+ }
+
+ start = '11011010'
+ stop = '1101011'
+
+ calculateLineHeight = Barcode._calculate15
+
+
+if __name__ == '__main__':
+
+ testbar = Standard2of5()
+
+ def test(value, format, file):
+ f = open(file,'wb')
+ testbar.generate(value,f, format)
+ f.close()
+
+ test('0123456789','png','test1.png')
+ test('9876543210','tiff','test1.tif')
+ test('9876543210','postscript','test1.ps')
+ test('0123456789','eps','test1.eps')
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r5963 - in trunk/gnue-common/src: . printing printing/barcodes,
jcater <=