From 7b9ec2e14886c0ab1f9ae3d31c130c039f18bafd Mon Sep 17 00:00:00 2001 From: "skye.yue" Date: Mon, 15 Jun 2026 14:21:31 +0800 Subject: [PATCH] fix: reduce alarm snapshot label obstruction --- src/cold_display_guard/alarm_snapshots.py | 12 ++++++----- tasks/todo.md | 25 ++++++++++++++++++++++- tests/test_alarm_snapshots.py | 19 +++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/cold_display_guard/alarm_snapshots.py b/src/cold_display_guard/alarm_snapshots.py index c48326d..be17817 100644 --- a/src/cold_display_guard/alarm_snapshots.py +++ b/src/cold_display_guard/alarm_snapshots.py @@ -62,6 +62,8 @@ ZONE_OVERLAY_PALETTE: tuple[tuple[int, int, int], ...] = ( TRASH_OVERLAY_RGB = (255, 64, 64) LABEL_TEXT_RGB = (255, 255, 255) LABEL_SHADOW_RGB = (0, 0, 0) +LABEL_BOX_ALPHA = 0.34 +LABEL_OUTLINE_ALPHA = 0.64 CJK_FONT_CANDIDATES = ( Path("/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc"), Path("/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.otf"), @@ -350,13 +352,13 @@ def render_region_labels_with_ffmpeg( def build_drawtext_filter(labels: list[OverlayLabel], font_file: Path, height: int) -> str: - font_size = max(14, min(30, round(height * 0.052))) + font_size = max(10, min(22, round(height * 0.036))) filters: list[str] = [] for label in labels: text = escape_drawtext_value(label.text) font = escape_drawtext_value(str(font_file)) color = rgb_to_hex(LABEL_TEXT_RGB) - box_color = "black@0.62" + box_color = f"black@{LABEL_BOX_ALPHA:.2f}" filters.append( "drawtext=" f"fontfile='{font}':" @@ -367,7 +369,7 @@ def build_drawtext_filter(labels: list[OverlayLabel], font_file: Path, height: i f"fontcolor={color}:" "box=1:" f"boxcolor={box_color}:" - "boxborderw=4" + "boxborderw=2" ) return ",".join(filters) @@ -442,8 +444,8 @@ def draw_region_label( box_height = min(box_height, height - y) if box_width < 6 or box_height < 6: return - fill_rect(rgb, width, height, x, y, box_width, box_height, LABEL_SHADOW_RGB, alpha=0.62) - draw_rect_outline(rgb, width, height, x, y, box_width, box_height, accent_rgb, alpha=0.9) + fill_rect(rgb, width, height, x, y, box_width, box_height, LABEL_SHADOW_RGB, alpha=LABEL_BOX_ALPHA) + draw_rect_outline(rgb, width, height, x, y, box_width, box_height, accent_rgb, alpha=LABEL_OUTLINE_ALPHA) draw_text(rgb, width, height, x + 2, y + 2, glyphs, LABEL_TEXT_RGB, LABEL_SHADOW_RGB) diff --git a/tasks/todo.md b/tasks/todo.md index c37a1a6..16309e7 100644 --- a/tasks/todo.md +++ b/tasks/todo.md @@ -315,4 +315,27 @@ - Remote health returned `status=ok` and `runtime_status=running`. - Remote container config shows the new thresholds. - After deployment, latest diagnostics stabilized at `zone_counts = {"1": 1, "2": 1, "6": 1}`. - - During a two-minute observation window after `13:25`, no new `batch_consumed` events were emitted; only expected pre-warning/alarm lifecycle events appeared for the occupied zones. +- During a two-minute observation window after `13:25`, no new `batch_consumed` events were emitted; only expected pre-warning/alarm lifecycle events appeared for the occupied zones. + +## Current Task: Reduce Alarm Snapshot Label Visual Obstruction + +**Goal:** Region labels on uploaded alarm screenshots should be smaller and more transparent so operators can inspect the food/display image underneath. + +**Design:** Keep the existing label content, placement, CJK font rendering, and per-zone colors. Only reduce the visual weight of the label layer by lowering font size, black label-box opacity, border width, and fallback label-box opacity. + +- [x] Inspect current alarm snapshot label rendering style. +- [x] Add a regression test for smaller ffmpeg drawtext label style. +- [x] Reduce drawtext font size and label-box opacity. +- [x] Keep fallback label renderer visually consistent with the ffmpeg path. +- [x] Run full local verification. +- [x] Deploy the updated snapshot overlay style to `xiaozheng@10.8.0.23`. +- [x] Verify remote runtime health and deployed label style. + +### Notes + +- Targeted snapshot test passed: `PYTHONPATH=src python3 -m unittest tests/test_alarm_snapshots.py -v`. +- Full local verification passed: `PYTHONPATH=src python3 -m unittest discover -s tests -v` (`103` tests). +- Remote verification passed: + - `GET /api/manage/health` returned `status=ok` and `runtime_status=running`. + - Running container uses `fontsize=13`, `boxcolor=black@0.34`, and `boxborderw=2` for region labels. + - `cold-display-guard-runtime` logs show normal startup after restart. diff --git a/tests/test_alarm_snapshots.py b/tests/test_alarm_snapshots.py index 639ee3d..d3b03ce 100644 --- a/tests/test_alarm_snapshots.py +++ b/tests/test_alarm_snapshots.py @@ -189,6 +189,25 @@ class AlarmSnapshotTests(unittest.TestCase): dockerfile = (Path(__file__).resolve().parents[1] / "Dockerfile").read_text(encoding="utf-8") self.assertIn("fonts-noto-cjk", dockerfile) + def test_drawtext_label_style_stays_small_and_translucent(self) -> None: + filter_text = alarm_snapshots.build_drawtext_filter( + [ + alarm_snapshots.OverlayLabel( + text="区域 1", + fallback_text="R1", + x=10, + y=20, + accent_rgb=(255, 196, 0), + ) + ], + Path("/tmp/NotoSansCJK-Regular.ttc"), + height=360, + ) + + self.assertIn("fontsize=13", filter_text) + self.assertIn("boxcolor=black@0.34", filter_text) + self.assertIn("boxborderw=2", filter_text) + def test_capture_alert_snapshot_encodes_frame_with_configured_calibration_overlay(self) -> None: encoded_frames: list[Frame] = []