Skip to content

Commit 91032f2

Browse files
authored
Merge pull request #61 from Kittl/CU-86c3mbjx8-Simplify-Vectorizer-Output
Minimize bad cases CU-86c3mbjx8
2 parents 43be3b5 + b059442 commit 91032f2

2 files changed

Lines changed: 57 additions & 10 deletions

File tree

vectorizing/solvers/color/ColorSolver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def solve(self):
3535
self.timer.end_timer()
3636

3737
self.timer.start_timer("Polygon Clipping")
38-
compound_paths = remove_layering(traced_bitmaps)
38+
compound_paths = remove_layering(traced_bitmaps, self.img)
3939
self.timer.end_timer()
4040

4141
return [compound_paths, colors, self.img.size[0], self.img.size[1]]

vectorizing/solvers/color/clip.py

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,70 @@
1-
from pathops import op, PathOp
1+
from pathops import op, PathOp, Path
22
from vectorizing.geometry.potrace import potrace_path_to_compound_path
33

4-
def remove_layering(traced_bitmaps):
4+
def create_background_rect(img, padding):
5+
"""
6+
Creates a rectangle that matches the image dimensions plus
7+
some padding.
8+
9+
Parameters:
10+
img: A Pillow image instance.
11+
12+
Returns:
13+
The rectangle.
14+
"""
15+
rect = Path()
16+
rect.moveTo(-padding, -padding)
17+
rect.lineTo(img.width + padding, -padding)
18+
rect.lineTo(img.width + padding, img.height + padding)
19+
rect.lineTo(-padding, img.height + padding)
20+
rect.close()
21+
return rect
22+
23+
def remove_layering(traced_bitmaps, img):
524
"""
625
Performs boolean operations on a list of traced bitmaps
726
to ensure that they are all disjoint.
827
9-
Parameters:
10-
traced_bitmaps: The list of traced bitmaps (potrace paths).
28+
This function uses a technique devised to try to minimize
29+
the holes created / outright failures of SKPath boolean operations.
30+
Even so, a failure can still happen (and often does), particularly
31+
for very intricate paths (usually coming from real world photographs).
32+
In such cases, the routine fallbacks to a mixture of disjoint paths
33+
(the ones for which the boolean operations didn't fail), and layered paths.
34+
35+
Parameters:
36+
traced_bitmaps: The list of traced bitmaps (potrace paths).
37+
img: A Pillow image.
1138
12-
Returns:
13-
The processed list of compound paths.
39+
Returns:
40+
The processed list of compound paths.
1441
"""
1542
compound_paths = [
1643
potrace_path_to_compound_path(traced) for traced in traced_bitmaps
1744
]
1845

46+
disjoint_paths = []
1947
for x in range(len(compound_paths) - 1):
20-
next = compound_paths[x + 1]
21-
compound_paths[x] = op(compound_paths[x], next, PathOp.DIFFERENCE)
48+
# Each base path has bigger padding to reduce
49+
# the amount of overlapping borders.
50+
base = create_background_rect(img, (x + 1) * 10)
51+
52+
to_subtract = Path()
53+
for y in range(0, x):
54+
to_subtract.addPath(disjoint_paths[y])
55+
to_subtract.addPath(compound_paths[x + 1])
56+
57+
try:
58+
result = op(base, to_subtract, PathOp.DIFFERENCE)
59+
except:
60+
break
61+
disjoint_paths.append(result)
62+
63+
for x in range(len(disjoint_paths)):
64+
try:
65+
disjoint_paths[x] = op(disjoint_paths[x], create_background_rect(img, 0), PathOp.INTERSECTION)
66+
except:
67+
return compound_paths
2268

23-
return compound_paths
69+
disjoint_paths = disjoint_paths + compound_paths[len(disjoint_paths) : len(compound_paths)]
70+
return disjoint_paths

0 commit comments

Comments
 (0)