Refine freehand exclusion polygons

Store freehand paths as closed polygons with thin outlines and fill the interior when masking, so free-drawn shapes behave like custom rectangles.
This commit is contained in:
lm
2025-10-17 17:11:18 +02:00
parent f678c403b7
commit 464855f365
2 changed files with 25 additions and 21 deletions
+9 -11
View File
@@ -266,12 +266,12 @@ class ImageProcessingMixin:
if shape.get("kind") == "rect":
x0, y0, x1, y1 = shape["coords"] # type: ignore[index]
outline.rectangle([x0, y0, x1, y1], outline=(255, 215, 0, 200), width=3)
elif shape.get("kind") == "stroke":
elif shape.get("kind") == "polygon":
points = shape.get("points", [])
if len(points) < 2:
continue
width_px = int(shape.get("width", 8))
outline.line(points, fill=(255, 215, 0, 200), width=width_px, joint="round")
path = points if points[0] == points[-1] else points + [points[0]]
outline.line(path, fill=(255, 215, 0, 200), width=2, joint="round")
return merged
def compute_stats_preview(self):
@@ -423,14 +423,12 @@ class ImageProcessingMixin:
],
fill=255,
)
elif kind == "stroke":
elif kind == "polygon":
points = shape.get("points")
if not points or len(points) < 2:
return
base_width = float(shape.get("width", 8)) # type: ignore[arg-type]
width_px = max(1, int(round(base_width * (scale_x + scale_y) / 2.0)))
scaled = [(px * scale_x, py * scale_y) for px, py in points] # type: ignore[misc]
draw.line(scaled, fill=255, width=width_px, joint="round")
draw.polygon(scaled, fill=255)
def _render_exclusion_overlays(self) -> None:
if not hasattr(self, "canvas_orig"):
@@ -449,16 +447,16 @@ class ImageProcessingMixin:
x0, y0, x1, y1, outline="yellow", width=3
)
self._exclude_canvas_ids.append(item)
elif kind == "stroke":
elif kind == "polygon":
points = shape.get("points")
if not points or len(points) < 2:
continue
width_px = int(shape.get("width", 8))
coords = [coord for point in points for coord in point] # type: ignore[misc]
closed = points if points[0] == points[-1] else points + [points[0]] # type: ignore[operator]
coords = [coord for point in closed for coord in point] # type: ignore[misc]
item = self.canvas_orig.create_line(
*coords,
fill="yellow",
width=width_px,
width=2,
smooth=True,
capstyle="round",
joinstyle="round",