python3 support

pull/3/head
Lingdong Huang 2019-10-27 03:32:11 -04:00
rodzic eac8073610
commit 2cfeb04e0d
3 zmienionych plików z 18 dodań i 15 usunięć

Wyświetl plik

@ -1,20 +1,22 @@
# linedraw # linedraw
Convert images to vectorized line drawings for plotters. Convert images to vectorized line drawings for plotters.
![Alt text](/screenshots/1.png?raw=true "") ![Alt text](./screenshots/1.png?raw=true "")
- Exports polyline-only svg file with optimized stroke order for plotters; - Exports polyline-only svg file with optimized stroke order for plotters;
- Sketchy style powered by Perlin noise; - Sketchy style powered by Perlin noise;
- Contour-only or hatch-only modes. - Contour-only or hatch-only modes.
## Dependencies ## Dependencies
Python 2, PIL/Pillow, numpy, OpenCV (Optional for better performance) Python 2 or 3, PIL/Pillow, numpy, OpenCV (Optional for better performance)
## Usage ## Usage
Convert an image to line drawing and export .SVG format: Convert an image to line drawing and export .SVG format:
```shell ```shell
$ python linedraw.py -i input.jpg -o output.svg $ python linedraw.py -i input.jpg -o output.svg
``` ```
Command specs: Command specs:
``` ```
usage: linedraw.py [-h] [-i [INPUT_PATH]] [-o [OUTPUT_PATH]] [-b] [-nc] [-nh] usage: linedraw.py [-h] [-i [INPUT_PATH]] [-o [OUTPUT_PATH]] [-b] [-nc] [-nh]
[--no_cv] [--hatch_size [HATCH_SIZE]] [--no_cv] [--hatch_size [HATCH_SIZE]]
@ -38,6 +40,7 @@ optional arguments:
Level of contour simplification. eg. 1, 2, 3 Level of contour simplification. eg. 1, 2, 3
``` ```
Python: Python:
```python ```python
import linedraw import linedraw
lines = linedraw.sketch("path/to/img.jpg") # return list of polylines, eg. lines = linedraw.sketch("path/to/img.jpg") # return list of polylines, eg.

Wyświetl plik

@ -22,11 +22,11 @@ try:
import numpy as np import numpy as np
import cv2 import cv2
except: except:
print "Cannot import numpy/openCV. Switching to NO_CV mode." print("Cannot import numpy/openCV. Switching to NO_CV mode.")
no_cv = True no_cv = True
def find_edges(IM): def find_edges(IM):
print "finding edges..." print("finding edges...")
if no_cv: if no_cv:
#appmask(IM,[F_Blur]) #appmask(IM,[F_Blur])
appmask(IM,[F_SobelX,F_SobelY]) appmask(IM,[F_SobelX,F_SobelY])
@ -39,7 +39,7 @@ def find_edges(IM):
def getdots(IM): def getdots(IM):
print "getting contour points..." print("getting contour points...")
PX = IM.load() PX = IM.load()
dots = [] dots = []
w,h = IM.size w,h = IM.size
@ -58,7 +58,7 @@ def getdots(IM):
return dots return dots
def connectdots(dots): def connectdots(dots):
print "connecting contour points..." print("connecting contour points...")
contours = [] contours = []
for y in range(len(dots)): for y in range(len(dots)):
for x,v in dots[y]: for x,v in dots[y]:
@ -91,7 +91,7 @@ def connectdots(dots):
def getcontours(IM,sc=2): def getcontours(IM,sc=2):
print "generating contours..." print("generating contours...")
IM = find_edges(IM) IM = find_edges(IM)
IM1 = IM.copy() IM1 = IM.copy()
IM2 = IM.rotate(-90,expand=True).transpose(Image.FLIP_LEFT_RIGHT) IM2 = IM.rotate(-90,expand=True).transpose(Image.FLIP_LEFT_RIGHT)
@ -128,7 +128,7 @@ def getcontours(IM,sc=2):
def hatch(IM,sc=16): def hatch(IM,sc=16):
print "hatching..." print("hatching...")
PX = IM.load() PX = IM.load()
w,h = IM.size w,h = IM.size
lg1 = [] lg1 = []
@ -184,13 +184,13 @@ def sketch(path):
lines = [] lines = []
if draw_contours: if draw_contours:
lines += getcontours(IM.resize((resolution/contour_simplify,resolution/contour_simplify*h/w)),contour_simplify) lines += getcontours(IM.resize((resolution//contour_simplify,resolution//contour_simplify*h//w)),contour_simplify)
if draw_hatch: if draw_hatch:
lines += hatch(IM.resize((resolution/hatch_size,resolution/hatch_size*h/w)),hatch_size) lines += hatch(IM.resize((resolution//hatch_size,resolution//hatch_size*h//w)),hatch_size)
lines = sortlines(lines) lines = sortlines(lines)
if show_bitmap: if show_bitmap:
disp = Image.new("RGB",(resolution,resolution*h/w),(255,255,255)) disp = Image.new("RGB",(resolution,resolution*h//w),(255,255,255))
draw = ImageDraw.Draw(disp) draw = ImageDraw.Draw(disp)
for l in lines: for l in lines:
draw.line(l,(0,0,0),5) draw.line(l,(0,0,0),5)
@ -199,13 +199,13 @@ def sketch(path):
f = open(export_path,'w') f = open(export_path,'w')
f.write(makesvg(lines)) f.write(makesvg(lines))
f.close() f.close()
print len(lines), "strokes." print("strokes.")
print "done." print("done.")
return lines return lines
def makesvg(lines): def makesvg(lines):
print "generating svg file..." print("generating svg file...")
out = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">' out = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">'
for l in lines: for l in lines:
l = ",".join([str(p[0]*0.5)+","+str(p[1]*0.5) for p in l]) l = ",".join([str(p[0]*0.5)+","+str(p[1]*0.5) for p in l])

Wyświetl plik

@ -4,7 +4,7 @@ from util import *
def sortlines(lines): def sortlines(lines):
print "optimizing stroke sequence..." print("optimizing stroke sequence...")
clines = lines[:] clines = lines[:]
slines = [clines.pop(0)] slines = [clines.pop(0)]
while clines != []: while clines != []: