Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mmulqueen/pyStrich
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.6
Choose a base ref
...
head repository: mmulqueen/pyStrich
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
  • 10 commits
  • 16 files changed
  • 3 contributors

Commits on Jul 26, 2015

  1. Datamatrix above 44 chars no longer causes sys.exit, instead DataTooL…

    …ongForImplementation exception thrown. See #2
    mmulqueen committed Jul 26, 2015
    Copy the full SHA
    6013231 View commit details
  2. Copy the full SHA
    54c6880 View commit details

Commits on Jun 23, 2016

  1. Code 39 support.

    mmulqueen committed Jun 23, 2016
    Copy the full SHA
    d33d147 View commit details

Commits on Jul 1, 2016

  1. Fixes #5

    mmulqueen committed Jul 1, 2016
    Copy the full SHA
    da8ccb9 View commit details

Commits on Jul 6, 2016

  1. Copy the full SHA
    62a0617 View commit details

Commits on Aug 24, 2016

  1. Add DXF rendering to 2D barcodes

    CAD programs often only support the import of vector graphics. Most
    common is the support of AutoCAD R10 DXF file format. Resulting files
    have been tested with Draftsight, SolidWorks and Allegro PCB.
    micjoc00 committed Aug 24, 2016
    Copy the full SHA
    9fe8bde View commit details

Commits on Sep 2, 2016

  1. Removed example dxf file and ignore it in future

    The text.dxf was added to the previous commit by error and will now be
    ignored for future commits.
    micjoc00 committed Sep 2, 2016
    Copy the full SHA
    15ce66b View commit details

Commits on Sep 5, 2016

  1. Merge pull request #7 from micjoc00/dxf2d-support

    Add DXF rendering to 2D barcodes - Thanks @micjoc00
    mmulqueen authored Sep 5, 2016
    Copy the full SHA
    fafe62f View commit details

Commits on Feb 9, 2018

  1. Expand .gitignore

    mmulqueen committed Feb 9, 2018
    Copy the full SHA
    fbdd270 View commit details
  2. Updated README to reflect known issues.

    This is in response to #8
    mmulqueen committed Feb 9, 2018
    Copy the full SHA
    2839fd1 View commit details
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -10,4 +10,7 @@ MANIFEST
datamatrix-test.png
pip-log.txt
test.png
test.dxf
testenv/
venv/
.idea/
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -3,10 +3,11 @@ pyStrich
pyStrich is a Python module to generate 1D and 2D barcodes. Currently it
supports

* code39
* code128
* ean13
* datamatrix
* qrcode
* qrcode - see [known issues](#known-issues)

Available from PyPI: https://pypi.python.org/pypi/pyStrich

@@ -27,12 +28,25 @@ print(encoder.get_ascii())
Relevant imports are:

```python
from pystrich.code39 import Code39Encoder
from pystrich.code128 import Code128Encoder
from pystrich.datamatrix import DataMatrixEncoder
from pystrich.ean13 import EAN13Encoder
from pystrich.qrcode import QRCodeEncoder
```

Known Issues
----------
Code39, Code128 and DataMatrix support is considered by the maintainer to be good and they are known to be used in
production.

The maintainer rarely uses EAN13 or QRCode support. You may wish to consider more actively maintained modules.

The maintainer has no plans to fix the following issues:

* Some QR codes cause an exception to be thrown - root cause unknown - [see issue 8](https://github.com/mmulqueen/pyStrich/issues/8).
* DataMatrix module only supports up to 174 characters or 348 digits of data - [see issue 2](https://github.com/mmulqueen/pyStrich/issues/2).

Background
----------
pyStrich is a fork of huBarcode module with modifications to support Python 3 (amongst other changes). pyStrich
13 changes: 13 additions & 0 deletions examples/code39.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Example code for code128 library"""


import logging
import sys
from pystrich.code39 import Code39Encoder

logging.getLogger("code39").setLevel(logging.DEBUG)
logging.getLogger("code39").addHandler(logging.StreamHandler(sys.stdout))

if __name__ == "__main__":
encoder = Code39Encoder(sys.argv[1])
encoder.save("test.png")
2 changes: 2 additions & 0 deletions examples/datamatrix.py
Original file line number Diff line number Diff line change
@@ -14,3 +14,5 @@
encoder = DataMatrixEncoder(sys.argv[1])
encoder.save("test.png")
print(encoder.get_ascii())
with open("test.dxf", "w") as text_file:
text_file.write(encoder.get_dxf(inverse=True, cellsize=0.1))
2 changes: 2 additions & 0 deletions examples/qrcode.py
Original file line number Diff line number Diff line change
@@ -13,3 +13,5 @@
ENCODER = QRCodeEncoder(sys.argv[1])
ENCODER.save("test.png", 3)
print(ENCODER.get_ascii())
with open("test.dxf", "w") as text_file:
text_file.write(ENCODER.get_dxf(inverse=False, cellsize=0.1))
52 changes: 52 additions & 0 deletions pystrich/code39/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Code-39 barcode encoder
All needed by the user is done via the Code39Encoder class:
>>> encoder = Code39Encoder("MIL-STD-1189")
>>> encoder.save("test.png")
You may use this under a BSD License.
"""
from .textencoder import TextEncoder
from .renderer import Code39Renderer
import logging

log = logging.getLogger("code39")


class Code39Encoder:
"""Top-level class which handles the overall process of
encoding input string and outputting the result"""

def __init__(self, text, full_ascii=False, options=None):
""" The options hash currently supports three options:
* ttf_font: absolute path to a truetype font file used to render the label
* ttf_fontsize: the size the label is drawn in
* label_border: number of pixels space between the barcode and the label
* bottom_border: number of pixels space between the label and the bottom border
"""

self.options = options
self.text = text
self.height = 0
self.width = 0
encoder = TextEncoder()

self.encoded_text = encoder.encode(self.text, full_ascii)
log.debug("Encoded text is %s", self.encoded_text)

self.bars = encoder.get_bars(self.encoded_text)
log.debug("Bars: %s", self.bars)

def get_imagedata(self, bar_width=3):
"""Write the matrix out to an PNG bytestream"""
barcode = Code39Renderer(self.bars, self.text, self.options)
imagedata = barcode.get_imagedata(bar_width)
self.width = barcode.image_width
self.height = barcode.image_height
return imagedata

def save(self, filename, bar_width=3):
"""Write the barcode out to an image file"""
Code39Renderer(
self.bars, self.text, self.options).write_file(filename, bar_width)
218 changes: 218 additions & 0 deletions pystrich/code39/encoding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
"""Encoding data tables for code39 barcode encoder
Source: MIL-STD-1189B, via: http://quicksearch.dla.mil/qsDocDetails.aspx?ident_number=36123"""

# Code39 encoding is deliberately represented in strings instead of bytestrings for ease of iteration.

# MIL-STD-1189B, page 21, Table VI
ascii_to_code39 = {
b"\x00": "%U", # NUL
b"\x01": "$A", # SOH
b"\x02": "$B", # STX
b"\x03": "$C", # ETX
b"\x04": "$D", # EOT
b"\x05": "$E", # ENQ
b"\x06": "$F", # ACK
b"\x07": "$G", # BEL
b"\x08": "$H", # BS
b"\x09": "$I", # HT
b"\x0A": "$J", # LF
b"\x0B": "$K", # VT
b"\x0C": "$L", # FF
b"\x0D": "$M", # CR
b"\x0E": "$N", # SO
b"\x0F": "$O", # SI
b"\x10": "$P", # DLE
b"\x11": "$Q", # DC1
b"\x12": "$R", # DC2
b"\x13": "$S", # DC3
b"\x14": "$T", # DC4
b"\x15": "$U", # NAK
b"\x16": "$V", # SYN
b"\x17": "$W", # ETB
b"\x18": "$X", # CAN
b"\x19": "$Y", # EM
b"\x1A": "$Z", # SUB
b"\x1B": "%A", # ESC
b"\x1C": "%B", # FS
b"\x1D": "%C", # GS
b"\x1E": "%D", # RS
b"\x1F": "%E", # US
b" ": " ", # Space
b"!": "/A",
b"\"": "/B",
b"#": "/C",
b"$": "/D",
b"%": "/E",
b"&": "/F",
b"'": "/G",
b"(": "/H",
b")": "/I",
b"*": "/J",
b"+": "/K",
b",": "/L",
b"-": "-",
b".": ".",
b"/": "/O",
b"0": "0",
b"1": "1",
b"2": "2",
b"3": "3",
b"4": "4",
b"5": "5",
b"6": "6",
b"7": "7",
b"8": "8",
b"9": "9",
b":": "/Z",
b";": "%F",
b"<": "%G",
b"=": "%H",
b">": "%I",
b"?": "%J",
b"@": "%V",
b"A": "A",
b"B": "B",
b"C": "C",
b"D": "D",
b"E": "E",
b"F": "F",
b"G": "G",
b"H": "H",
b"I": "I",
b"J": "J",
b"K": "K",
b"L": "L",
b"M": "M",
b"N": "N",
b"O": "O",
b"P": "P",
b"Q": "Q",
b"R": "R",
b"S": "S",
b"T": "T",
b"U": "U",
b"V": "V",
b"W": "W",
b"X": "X",
b"Y": "Y",
b"Z": "Z",
b"[": "%K",
b"\\": "%L",
b"]": "%M",
b"^": "%N",
b"_": "%O",
b"`": "%W",
b"a": "+A",
b"b": "+B",
b"c": "+C",
b"d": "+D",
b"e": "+E",
b"f": "+F",
b"g": "+G",
b"h": "+H",
b"i": "+I",
b"j": "+J",
b"k": "+K",
b"l": "+L",
b"m": "+M",
b"n": "+N",
b"o": "+O",
b"p": "+P",
b"q": "+Q",
b"r": "+R",
b"s": "+S",
b"t": "+T",
b"u": "+U",
b"v": "+V",
b"w": "+W",
b"x": "+X",
b"y": "+Y",
b"z": "+Z",
b"{": "%P",
b"|": "%Q",
b"}": "%R",
b"~": "%S",
b"\x7f": "%T" # DEL
}

ascii_ord_to_code39 = {ord(k): v for k, v in ascii_to_code39.items()}

# MIL-STD-1189B, page 8
# 1 represents a wide bar/gap, 0 represents a narrow bar/gap
code39_bars_and_gaps = {
# symbol: (bars, gaps)
# Numbers
"1": ("10001", "0100"),
"2": ("01001", "0100"),
"3": ("11000", "0100"),
"4": ("00101", "0100"),
"5": ("10100", "0100"),
"6": ("01100", "0100"),
"7": ("00011", "0100"),
"8": ("10010", "0100"),
"9": ("01010", "0100"),
"0": ("00110", "0100"),
# Letters
"A": ("10001", "0010"),
"B": ("01001", "0010"),
"C": ("11000", "0010"),
"D": ("00101", "0010"),
"E": ("10100", "0010"),
"F": ("01100", "0010"),
"G": ("00011", "0010"),
"H": ("10010", "0010"),
"I": ("01010", "0010"),
"J": ("00110", "0010"),
"K": ("10001", "0001"),
"L": ("01001", "0001"),
"M": ("11000", "0001"),
"N": ("00101", "0001"),
"O": ("10100", "0001"),
"P": ("01100", "0001"),
"Q": ("00011", "0001"),
"R": ("10010", "0001"),
"S": ("01010", "0001"),
"T": ("00110", "0001"),
"U": ("10001", "1000"),
"V": ("01001", "1000"),
"W": ("11000", "1000"),
"X": ("00101", "1000"),
"Y": ("10100", "1000"),
"Z": ("01100", "1000"),
"-": ("00011", "1000"),
".": ("10010", "1000"),
" ": ("01010", "1000"),
"*": ("00110", "1000"),
"$": ("00000", "1110"),
"/": ("00000", "1101"),
"+": ("00000", "1011"),
"%": ("00000", "0111")
}


def build_code39_encodings():
"""Change representations so that 1 represents a narrow bar and 0 represents a narrow gap.
# (11 = wide bar, 00 = wide gap)"""
encodings = {}
for symbol, bars_and_gaps in code39_bars_and_gaps.items():
bars, gaps = bars_and_gaps
new_seq = []
for i in range(5):
if bars[i] == "0":
new_seq.extend("1")
else:
new_seq.extend("11")
if i == 4:
break # No 5th gap
if gaps[i] == "0":
new_seq.extend("0")
else:
new_seq.extend("00")
encodings[symbol] = "".join(new_seq)
assert len(encodings[symbol]) == 12 # 3 doubles and 6 singles = 12 total
return encodings

code39_encodings = build_code39_encodings()


Loading