mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-08-01 16:58:06 +00:00
perf(web): stream the preview PNG raw instead of PIL decode + re-encode
display_preview_generator() opened each changed snapshot with PIL and re-encoded it to PNG just to base64 it — but /tmp/led_matrix_preview.png already IS a PNG, written atomically by the display service (tmp file + os.replace in display_manager.py), so a partially-written file can never be observed. Read the bytes and base64 them directly: identical payload (front-end consumes data:image/png;base64 — verified in base.html), one full image decode+encode per frame less on the same Pi that's driving the matrix. The existing mtime skip and viewer-marker throttling are unchanged (they already covered the "skip unchanged frames" concern). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KEZK1P1Q1fu5pcuVrkrCFZ
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
c548cfeabe
commit
4552e823a1
+16
-18
@@ -615,8 +615,6 @@ def system_status_generator():
|
|||||||
def display_preview_generator():
|
def display_preview_generator():
|
||||||
"""Generate display preview updates from snapshot file"""
|
"""Generate display preview updates from snapshot file"""
|
||||||
import base64
|
import base64
|
||||||
from PIL import Image
|
|
||||||
import io
|
|
||||||
|
|
||||||
snapshot_path = "/tmp/led_matrix_preview.png" # nosec B108 - fixed path matches display_manager; only read here
|
snapshot_path = "/tmp/led_matrix_preview.png" # nosec B108 - fixed path matches display_manager; only read here
|
||||||
# Viewer marker: this generator only runs while the broadcaster has
|
# Viewer marker: this generator only runs while the broadcaster has
|
||||||
@@ -658,23 +656,23 @@ def display_preview_generator():
|
|||||||
# Only read if file is new or has been updated
|
# Only read if file is new or has been updated
|
||||||
if last_modified is None or current_modified > last_modified:
|
if last_modified is None or current_modified > last_modified:
|
||||||
try:
|
try:
|
||||||
# Read and encode the image
|
# The snapshot is already a PNG, written atomically by
|
||||||
with Image.open(snapshot_path) as img:
|
# the display service (tmp + os.replace in
|
||||||
# Convert to PNG and encode as base64
|
# display_manager), so pass the raw bytes straight
|
||||||
buffer = io.BytesIO()
|
# through instead of PIL-decoding and re-encoding —
|
||||||
img.save(buffer, format='PNG')
|
# identical payload, much less CPU on the Pi.
|
||||||
img_str = base64.b64encode(buffer.getvalue()).decode('utf-8')
|
with open(snapshot_path, 'rb') as f:
|
||||||
|
img_str = base64.b64encode(f.read()).decode('utf-8')
|
||||||
|
|
||||||
preview_data = {
|
preview_data = {
|
||||||
'timestamp': time.time(),
|
'timestamp': time.time(),
|
||||||
'width': width,
|
'width': width,
|
||||||
'height': height,
|
'height': height,
|
||||||
'image': img_str
|
'image': img_str
|
||||||
}
|
}
|
||||||
last_modified = current_modified
|
last_modified = current_modified
|
||||||
yield preview_data
|
yield preview_data
|
||||||
except Exception: # nosec B110 - SSE preview file may be mid-write; transient error, skip this update
|
except Exception: # nosec B110 - transient read error (e.g. file rotated away); skip this update
|
||||||
# File might be being written, skip this update
|
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
# No snapshot available
|
# No snapshot available
|
||||||
|
|||||||
Reference in New Issue
Block a user