Add Flip filter with bool option support and calibration UI polish
- New FlipFilter with horizontal/vertical bool options (np.fliplr/flipud) - Add bool option type to filter system (base.py validate, app.js toggle UI) - Rearrange calibration preview: direction toggle above LED count - Normalize direction/offset control heights, brighten offset icon Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -77,13 +77,16 @@ class PostprocessingFilter(ABC):
|
||||
val = float(raw)
|
||||
elif opt_def.option_type == "int":
|
||||
val = int(raw)
|
||||
elif opt_def.option_type == "bool":
|
||||
val = bool(raw) if not isinstance(raw, bool) else raw
|
||||
else:
|
||||
val = raw
|
||||
# Clamp to range
|
||||
if opt_def.min_value is not None and val < opt_def.min_value:
|
||||
val = opt_def.min_value
|
||||
if opt_def.max_value is not None and val > opt_def.max_value:
|
||||
val = opt_def.max_value
|
||||
# Clamp to range (skip for bools)
|
||||
if opt_def.option_type != "bool":
|
||||
if opt_def.min_value is not None and val < opt_def.min_value:
|
||||
val = opt_def.min_value
|
||||
if opt_def.max_value is not None and val > opt_def.max_value:
|
||||
val = opt_def.max_value
|
||||
cleaned[opt_def.key] = val
|
||||
return cleaned
|
||||
|
||||
|
||||
@@ -280,3 +280,43 @@ class AutoCropFilter(PostprocessingFilter):
|
||||
result = image_pool.acquire(cropped_h, cropped_w, channels)
|
||||
np.copyto(result, image[top:bottom, left:right])
|
||||
return result
|
||||
|
||||
|
||||
@FilterRegistry.register
|
||||
class FlipFilter(PostprocessingFilter):
|
||||
"""Flips the image horizontally and/or vertically."""
|
||||
|
||||
filter_id = "flip"
|
||||
filter_name = "Flip"
|
||||
|
||||
@classmethod
|
||||
def get_options_schema(cls) -> List[FilterOptionDef]:
|
||||
return [
|
||||
FilterOptionDef(
|
||||
key="horizontal",
|
||||
label="Horizontal",
|
||||
option_type="bool",
|
||||
default=False,
|
||||
min_value=None,
|
||||
max_value=None,
|
||||
step=None,
|
||||
),
|
||||
FilterOptionDef(
|
||||
key="vertical",
|
||||
label="Vertical",
|
||||
option_type="bool",
|
||||
default=False,
|
||||
min_value=None,
|
||||
max_value=None,
|
||||
step=None,
|
||||
),
|
||||
]
|
||||
|
||||
def process_image(self, image: np.ndarray, image_pool: ImagePool) -> Optional[np.ndarray]:
|
||||
h = self.options.get("horizontal", False)
|
||||
v = self.options.get("vertical", False)
|
||||
if h:
|
||||
image[:] = np.fliplr(image)
|
||||
if v:
|
||||
image[:] = np.flipud(image)
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user