v3.0.0 — Stable Release
This is the first stable v3 release, graduating from the v2.1 baseline. The headline change is a ~250× faster image rendering pipeline via Numba JIT compilation, plus a full UI redesign, face-aware dithering, and a much broader set of supported image formats.
Performance
- ~250× faster dithering on Raspberry Pi — the inner pixel loop is now compiled to native code via Numba JIT (
@numba.njit(nogil=True)). A full 3200×1600 panel converts in 1–2 seconds instead of 4–8 minutes. - Memory-bounded pipeline — stripe-based rendering keeps peak memory at ≤ 50 MB per render regardless of source image size.
- Panel cache compressed with zstd level 1 — cached
.binpanels shrink ~50% on disk with negligible CPU overhead. - Parallel render pool — configurable thread count overlaps renders when images are queued; safe because the Numba loop releases the GIL.
Image Formats
- AVIF, JPEG XL (.jxl), WebP fully supported at upload and in the conversion pipeline.
- SVG support via resvg-py — vector files are rasterised to the panel resolution before dithering.
- HEIC added to the recognised extension list.
Dithering & Image Processing
- B&W image detection — images are classified as colour or greyscale at import; B&W images are routed through a dedicated pipeline with a pure black-and-white palette LUT, eliminating colour speckle artefacts on greyscale photos.
- Face-aware dithering with CLAHE protection — YuNet (OpenCV DNN) detects all faces in the image; detected face regions are excluded from CLAHE contrast enhancement with a Gaussian feather at the boundary, preserving skin tones.
- Face bounding box overlay in the dither preview shows which regions are being protected.
- Three independent pipelines: default (colour), B&W, and face — each with its own preset, configurable independently.
- Floyd-Steinberg (neutral) preset added as an option for B&W images.
- Crop-to-fill threshold — eliminates letterbox bands for near-fill images.
Web UI
- Complete redesign with a Japanese paper / washi aesthetic.
- Per-screen orientation override — each frame can be locked to landscape or portrait independently of the global setting. Both orientations are pre-rendered so serving the right one is instant.
- Hot-reload config — settings changes take effect without restarting the server.
- Failed image list — images that fail conversion are shown with error details, file size, and dimensions; supports per-image retry, delete, and bulk delete-all/retry-all.
- Dither preview in the config panel, updating live as settings change; includes the face bounding box overlay.
- Version shown in footer — confirms which build is running without checking the command line.
- ETA estimator — the status bar shows estimated time remaining for image conversion batches.
- Self-hosted Shippori Mincho font — no external network requests.
Firmware
- Dual-network WiFi — two SSID/password pairs configurable in NVS; the setup tool configures both.
- Battery percentage shown alongside voltage in the overdue warning displayed on screen.
- Graceful HTTP 503 handling — on pool-empty or still-converting responses, the firmware silently retries at the server interval rather than showing a "no images" screen.
- Firmware unit test suite (42 tests) running on the host via a CI job (ESP-IDF v5.5.3 / ESP32-S3).
Server & Packaging
- mDNS/Bonjour advertisement — server is discoverable as
hokku.local(configurable hostname) without knowing its IP. - Debian postinst stops the service before pip installs to prevent port-in-use failures on upgrade.
- Python package renamed from
webservertohokku_server. - Raspberry Pi installer improvements: wizard UI, mDNS integration, auto-download of latest release
.debfrom GitHub.