tatarize / potrace

Pure Python Port of Potrace
GNU General Public License v2.0
93 stars 15 forks source link

Python Potrace

Pure Python Port of Potrace. This is a python port of Peter Selinger's Potrace (based on 1.16 code).

head-orig3

Note: This image has been scaled up by a factor of 3.

head-scaled

This port is needed because many python hooks to the original code such as pypotrace have installation issues and compilation problems with some OSes. This potrace is written in pure python and will be compatible with basically anything.

Installing

To install or use as a requirement:

Potrace-CLI

If you wish to use the Command Line Interface that is stored in a sister project potrace-cli (https://github.com/tatarize/potrace-cli). This can be installed with:

or:

The cli project contains valid console script entrypoints for potrace. If you install the command-line package it will add potracer to your console scripts. Note the -r suffix so that it does not interfere with potrace that may be otherwise installed.

Requirements

Speed

Being written in python this code may be about 500x slower than the pure-c potrace. It is however fast enough for general use.

How To Use

This is a barebones script that uses potracer to convert a given file to an svg. The file loading is performed with Pillow. The file saving is done iterating over the curves inside the plist to produce the SVG with the corners and curves of the potrace structures.

Note: The bm.trace() is the primary function call needed for potrace.

import sys
from PIL import Image
from potrace import Bitmap, POTRACE_TURNPOLICY_MINORITY  # `potracer` library

def file_to_svg(filename: str):
    try:

        image = Image.open(filename)
    except IOError:
        print("Image (%s) could not be loaded." % filename)
        return
    bm = Bitmap(image, blacklevel=0.5)
    # bm.invert()
    plist = bm.trace(
        turdsize=2,
        turnpolicy=POTRACE_TURNPOLICY_MINORITY,
        alphamax=1,
        opticurve=False,
        opttolerance=0.2,
    )
    with open(f"{filename}.svg", "w") as fp:
        fp.write(
            f'''<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{image.width}" height="{image.height}" viewBox="0 0 {image.width} {image.height}">''')
        parts = []
        for curve in plist:
            fs = curve.start_point
            parts.append(f"M{fs.x},{fs.y}")
            for segment in curve.segments:
                if segment.is_corner:
                    a = segment.c
                    b = segment.end_point
                    parts.append(f"L{a.x},{a.y}L{b.x},{b.y}")
                else:
                    a = segment.c1
                    b = segment.c2
                    c = segment.end_point
                    parts.append(f"C{a.x},{a.y} {b.x},{b.y} {c.x},{c.y}")
            parts.append("z")
        fp.write(f'<path stroke="none" fill="black" fill-rule="evenodd" d="{"".join(parts)}"/>')
        fp.write("</svg>")

if __name__ == '__main__':
    file_to_svg(sys.argv[1])

Parallel Projects

This project intentionally duplicates a considerable amount of the API of pypotrace such that this library can be used as a drop-in replacement.

To permit performing potrace commands from the commandline, this library offers CLI potrace as an optional package.

License

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.

Furthermore, this is permitted to be relicensed under any terms the Peter Selinger's original Potrace is licensed under. If he broadly publishes the software under a more permissive license this port should be considered licensed as such as well. Further, if you purchase a proprietary license for inclusion within commercial software under his Dual Licensing program your use of this software shall be under whatever terms he permits for that. Any contributions to this port must be made under equally permissive terms.

"Potrace" is a trademark of Peter Selinger. Permission granted by Peter Selinger.