kopia lustrzana https://github.com/LingDong-/linedraw
python3 support
rodzic
eac8073610
commit
2cfeb04e0d
|
@ -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.
|
||||||
|
|
24
linedraw.py
24
linedraw.py
|
@ -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])
|
||||||
|
|
|
@ -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 != []:
|
||||||
|
|
Ładowanie…
Reference in New Issue