diff --git a/pdf417gen/console.py b/pdf417gen/console.py index 79abba8..d09c8d1 100644 --- a/pdf417gen/console.py +++ b/pdf417gen/console.py @@ -1,8 +1,8 @@ -import sys +import sys, os from argparse import ArgumentParser -from pdf417gen import encode, render_image +from pdf417gen import encode, render_image, render_svg def print_usage(): @@ -61,6 +61,10 @@ def get_parser(): parser.add_argument("-o", "--output", dest="output", type=str, help="Target file (if not given, will just show the barcode).") + parser.add_argument("-k", "--kind", type=str, default='image', + help=" what kind of image to produce eg image|svg " + "(default is image).") + return parser @@ -84,23 +88,51 @@ def do_encode(args): encoding=args.encoding, ) - image = render_image( - codes, - scale=args.scale, - ratio=args.ratio, - padding=args.padding, - fg_color=args.fg_color, - bg_color=args.bg_color, - ) + if args.kind=='svg': + xml = render_svg( + codes, + scale=args.scale, + ratio=args.ratio, + padding=args.padding, + fg_color=args.fg_color, + bg_color=args.bg_color, + ) + import xml.etree.ElementTree as ET + svg = ET.tostring(xml.getroot()) + if args.output: #we need to show it + with open(args.output,'w') as f: + f.write(svg) + else: + import tempfile + try: + from PIL import ImageShow + except ImportError: + print('!!!!! unable to show svg') + f, afn = tempfile.mkstemp(suffix='.svg') + os.write(f,svg) + os.close(f) + for v in ImageShow._viewers: + if v.show_file(afn): break + else: + os.remove(afn) + print('!!!!! cannot find svg viewer') + else: + image = render_image( + codes, + scale=args.scale, + ratio=args.ratio, + padding=args.padding, + fg_color=args.fg_color, + bg_color=args.bg_color, + ) + if args.output: + image.save(args.output) + else: + image.show() except Exception as e: print_err(str(e)) return - if args.output: - image.save(args.output) - else: - image.show() - def main(): command = sys.argv[1] if len(sys.argv) > 1 else None diff --git a/pdf417gen/rendering.py b/pdf417gen/rendering.py index 72cd8eb..c0ec120 100644 --- a/pdf417gen/rendering.py +++ b/pdf417gen/rendering.py @@ -1,6 +1,12 @@ -from PIL import Image, ImageColor, ImageOps from xml.etree.ElementTree import ElementTree, Element, SubElement +try: + from PIL import Image, ImageColor, ImageOps +except ImportError: + Image = None + ImageColor = None + ImageOps = None + def barcode_size(codes): """Returns the barcode size in modules.""" @@ -29,6 +35,7 @@ def modules(codes): def parse_color(color): + assert ImageColor, "Module PIL is not installed" return ImageColor.getrgb(color) @@ -36,7 +43,11 @@ def rgb_to_hex(color): return '#{0:02x}{1:02x}{2:02x}'.format(*color) -def render_image(codes, scale=3, ratio=3, padding=20, fg_color="#000", bg_color="#FFF"): +def render_image(codes, scale=3, ratio=3, padding=20, fg_color="#000", + bg_color="#FFF"): + + assert Image and ImageOps, "Module PIL is not installed" + width, height = barcode_size(codes) # Translate hex code colors to RGB tuples @@ -58,32 +69,45 @@ def render_image(codes, scale=3, ratio=3, padding=20, fg_color="#000", bg_color= return image -def render_svg(codes, scale=3, ratio=3, color="#000", description=None): +def render_svg(codes, scale=3, ratio=3, padding=20, fg_color="#000", bg_color=None, description=None): # Barcode size in modules width, height = barcode_size(codes) + padding = max(padding,0) #disallow negative padding # Size of each module scale_x = scale scale_y = scale * ratio - color = rgb_to_hex(parse_color(color)) + fg_color = rgb_to_hex(parse_color(fg_color)) - root = Element('svg', { - "version": "1.1", - "xmlns": "http://www.w3.org/2000/svg", - "width": str(width * scale_x), - "height": str(height * scale_y), - }) + w = str(width * scale_x+2*padding) + h = str(height * scale_y+2*padding) + root = Element('svg', dict( + version = "1.1", + xmlns = "http://www.w3.org/2000/svg", + width = w, + height = h, + )) if description: description_element = SubElement(root, 'description') description_element.text = description - group = SubElement(root, 'g', { - "id": "barcode", - "fill": color, - "stroke": "none" - }) + if bg_color is not None: + SubElement(root, 'rect', dict( + x = "0", + y = "0", + width = w, + height = h, + fill = bg_color, + )) + + group = SubElement(root, 'g', dict( + id = "barcode", + fill = fg_color, + stroke = "none", + transform="translate(%s,%s)" % (padding,padding), + )) # Generate the barcode modules for col_id, row_id, visible in modules(codes): @@ -91,11 +115,11 @@ def render_svg(codes, scale=3, ratio=3, color="#000", description=None): y = row_id * scale_y if visible: - SubElement(group, 'rect', { - "x": str(x), - "y": str(y), - "width": str(scale_x), - "height": str(scale_y), - }) + SubElement(group, 'rect', dict( + x = str(x), + y = str(y), + width = str(scale_x), + height = str(scale_y), + )) return ElementTree(element=root) diff --git a/tests/test_renderers.py b/tests/test_renderers.py index 2eaf272..f4fa6b8 100644 --- a/tests/test_renderers.py +++ b/tests/test_renderers.py @@ -22,8 +22,9 @@ def test_render_svg(): scale = 2 ratio = 4 description = "hi there" + padding = 5 - tree = render_svg(codes, scale=scale, ratio=ratio, description=description) + tree = render_svg(codes, scale=scale, ratio=ratio, description=description, padding=padding) assert isinstance(tree, ElementTree) assert tree.findtext("description") == description @@ -32,8 +33,8 @@ def test_render_svg(): root = tree.getroot() - assert root.get("width") == str(width * scale) - assert root.get("height") == str(height * scale * ratio) + assert root.get("width") == str(width * scale+2*padding) + assert root.get("height") == str(height * scale * ratio + 2*padding) assert root.get("version") == "1.1" assert root.get("xmlns") == "http://www.w3.org/2000/svg"