From 666ec2fe0a4871f8adfef2a10f9015974395a980 Mon Sep 17 00:00:00 2001 From: Chuck <33324927+ChuckBuilds@users.noreply.github.com> Date: Wed, 2 Sep 2026 16:44:09 -0400 Subject: [PATCH] docs(static-image): document every setting, with real renders Documentation only; no behaviour change. All 23 settings are covered, including the per-image schedule object the old README never mentioned. Two of them would otherwise be discovered by staring at a panel that never changes: - rotation_mode "date_based" is a stub. The source comment says "Future implementation" and it returns the first available image every time. The option is offered in the UI, so silently doing nothing is worse than saying so. - rotation_mode "time_based" does nothing on its own. It also needs rotation_settings.time_intervals.enabled set to true, and with that switch off the image never advances. The two rotation intervals are separated, because they look interchangeable and are not: image_rotation_interval always applies and is the one most people want (falling back to display_duration when unset), while time_intervals.interval_seconds is read only in time_based mode. Per-image schedules get their own section, along with the trap that schedule.enabled defaults to false -- so a carefully configured window is ignored until it is switched on -- and that scheduling every image out at once leaves nothing eligible to draw. fit_to_display and preserve_aspect_ratio get a four-panel comparison against a deliberately wide sample, since "fitted", "unfitted", "letterboxed" and "stretched" are easier to recognise than to describe. Audits before opening: no config token dropped, all 23 schema leaves documented, no broken TOC anchors, and the section check surfaced the per-format guidance and the set_image_path/reload_image API, both restored -- the methods were verified to exist before documenting them rather than trusted from the old README. Rotation itself is not screenshotted: every rotation_mode starts on the first eligible image and the differences only appear across frames, so that behaviour is documented from the source and the README says as much. Co-Authored-By: Claude Opus 5 --- README.md | 2 +- docs/assets/static-image/background-color.png | Bin 0 -> 19077 bytes docs/assets/static-image/fit-and-aspect.png | Bin 0 -> 18021 bytes docs/assets/static-image/hero.png | Bin 0 -> 2810 bytes docs/assets/static-image/panel-sizes.png | Bin 0 -> 26726 bytes docs/assets/static-image/sample/mark-a.png | Bin 0 -> 391 bytes docs/assets/static-image/sample/mark-b.png | Bin 0 -> 391 bytes .../static-image/sample/transparent.png | Bin 0 -> 383 bytes docs/assets/static-image/sample/wide.png | Bin 0 -> 315 bytes docs/assets/static-image/shots.json | 310 ++++++++++++ plugins.json | 4 +- plugins/static-image/README.md | 441 +++++++++++------- plugins/static-image/manifest.json | 10 +- 13 files changed, 600 insertions(+), 167 deletions(-) create mode 100644 docs/assets/static-image/background-color.png create mode 100644 docs/assets/static-image/fit-and-aspect.png create mode 100644 docs/assets/static-image/hero.png create mode 100644 docs/assets/static-image/panel-sizes.png create mode 100644 docs/assets/static-image/sample/mark-a.png create mode 100644 docs/assets/static-image/sample/mark-b.png create mode 100644 docs/assets/static-image/sample/transparent.png create mode 100644 docs/assets/static-image/sample/wide.png create mode 100644 docs/assets/static-image/shots.json diff --git a/README.md b/README.md index 9fae8532..d11c8b75 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ curl -X POST http://your-pi-ip:5000/api/v3/plugins/install \ | Plugin | Description | Preview | |--------|-------------|---------| | [Music Player](./plugins/ledmatrix-music/) | Now playing with album art (Spotify & YouTube Music) | | -| [Static Image Display](./plugins/static-image/) | Image display with scaling and transparency | | +| [Static Image Display](./plugins/static-image/) | Image display with scaling and transparency | static-image on an LED panel | ### Content (2) diff --git a/docs/assets/static-image/background-color.png b/docs/assets/static-image/background-color.png new file mode 100644 index 0000000000000000000000000000000000000000..fac023aa25a469f2abc2d311da67e80b89d0d4f3 GIT binary patch literal 19077 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 literal 0 HcmV?d00001 diff --git a/docs/assets/static-image/hero.png b/docs/assets/static-image/hero.png new file mode 100644 index 0000000000000000000000000000000000000000..d0d194301a297d055d2847111e9959995b459443 GIT binary patch literal 2810 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�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 literal 0 HcmV?d00001 diff --git a/docs/assets/static-image/sample/mark-a.png b/docs/assets/static-image/sample/mark-a.png new file mode 100644 index 0000000000000000000000000000000000000000..cc97044318974e98242b3505a9dd14cc1e76c811 GIT binary patch literal 391 zcmV;20eJq2P)vqEY`8JyVhRC&8h|5w@Hv8BY)g*TyOvY*%YN6dXM z-=D>Fg%%9gY>?2Z=~9gmdNF=hLxkRp=WYmkHlITSwG!tfMN24|ti>V0Nal}d4U} zgUsRiz~MbG^@z+t<}f`m@-Ue5hRk8^FWBi?%wF)Br6L zqaB$;%uPL3L9AwS2W){oS~)9lE%s^*M-#O+I~?sCN+&#n6fM+BoQqTqA(s%_O;b~B lx6RFAxpA_$t+N+0=MS%ak=Zs6NxA?4002ovPDHLkV1lX5vGo7| literal 0 HcmV?d00001 diff --git a/docs/assets/static-image/sample/mark-b.png b/docs/assets/static-image/sample/mark-b.png new file mode 100644 index 0000000000000000000000000000000000000000..413f77d6b8ec4fb8d3d9da02fe77c97026b72a12 GIT binary patch literal 391 zcmV;20eJq2P)T znS)FDZ+S%KAajs8IL-exugDx^4l)OsgUmtZAajs8$Q)YymeQJguTM2sc}wRwvWkq% zLFRCO;P4z+dPL?Rb6B33c^a&FL*}q{a>gpSz7B7|)`gj>;E|WG*Ld{R;=O_7Y=EAL z(T>a^=B5#=AXYQE1NK0QR!RkKMXJVdG*NGFhogf-?Sv&bqlH$9b8%Kf$R)&f)6^2% lZF6f_Zk!x#>+FTh`3JX~llgy}>lOe2002ovPDHLkV1oW3wcP*! literal 0 HcmV?d00001 diff --git a/docs/assets/static-image/sample/transparent.png b/docs/assets/static-image/sample/transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..fd63adc20de182beeacb7f627655387baa9d7029 GIT binary patch literal 383 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV080zaSW-L^LDo5q9Y0%&d%@Z z)6>72*I&FPCcv9-9V)bn&v>cBWfR}U-KlKS$vrb)pV9H19%``1NHOeYg_}|i`{Rk7 z5AvSvO}^=OOgXGMb@qN?8N=sKBSijtb@wF)F52V&X2py(N=K5K9@d@6O7HPG8MFSAbV+2pkcWY1QsH43!vzE`_G^gzdfn>7~?ohseOUM{!e_uc=i zItAJV+ST9xm(;gO{J;F4lnt+w3v%kx83!eJgqcT>+^S6-pO zjgd=(lS3cr23^?b8&vPH{bZ0apWrSdN`>3Ten$ycjeBFPZQ@It7H%Sz1Ex|T8JT&N#X4Wo5DSF zw%z3XbKq@Ft%NnBhcHOkmthHKg9+mVHHJ$p4zn0A1jF7l-rMW{mvj9d#|`UB_itP$ zj88RIBTxi+KbxF8%_*Py`Fzb3UTz}nzrJwc5l)E9c5kxgY*0KB5R>B!3={@WS3j3^ HP6:5000`, go to **Plugin Manager**, find **Static Image +Display** in the **Plugin Store** section, and click **Install**. Images are +uploaded from the plugin's own tab. + +**Manually.** Copy this directory into your LEDMatrix `plugin-repos/` and +restart the display service. + +`enabled` defaults to **`false`**, so nothing appears until you switch the +plugin on. + +--- + +## Quick Start ```json { - "enabled": true, - "images": [ - { "id": "logo", "path": "assets/static_images/my_logo.png" } - ], - "fit_to_display": true, - "preserve_aspect_ratio": true, - "background_color": [0, 0, 0], - "display_duration": 10 + "static-image": { + "enabled": true, + "images": [ + { "id": "logo", "path": "assets/plugins/static-image/logo.png" } + ] + } } ``` -### Multiple images with rotation +Several images on a rotation: ```json { - "enabled": true, - "images": [ - { "id": "logo_a", "path": "assets/static_images/logo_a.png" }, - { "id": "logo_b", "path": "assets/static_images/logo_b.png" }, - { "id": "logo_c", "path": "assets/static_images/logo_c.png" } - ], - "image_config": { - "mode": "multiple", - "rotation_mode": "sequential" - }, - "rotation_settings": { - "sequential_loop": true - }, - "image_rotation_interval": 15, - "fit_to_display": true, - "preserve_aspect_ratio": true, - "background_color": [0, 0, 0], - "display_duration": 30 + "static-image": { + "enabled": true, + "image_config": { "mode": "multiple", "rotation_mode": "sequential" }, + "image_rotation_interval": 15, + "images": [ + { "id": "logo", "path": "assets/plugins/static-image/logo.png", "display_order": 1 }, + { "id": "badge", "path": "assets/plugins/static-image/badge.png", "display_order": 2 }, + { "id": "banner", "path": "assets/plugins/static-image/banner.png", "display_order": 3 } + ] + } } ``` -### Configuration Options +--- -The full schema lives in -[`config_schema.json`](config_schema.json) — the web UI form is generated -from it. Key options: +## Adding Images -| Key | Default | Notes | -|---|---|---| -| `enabled` | `false` | Master switch | -| `images` | `[]` | Array of image entries (each an object with a `path` and an optional per-image `schedule`), managed via the file-upload widget. See **Per-Image Scheduling** below. | -| `image_config.mode` | `"single"` | How images are presented: `"single"` or `"multiple"` | -| `image_config.rotation_mode` | `"sequential"` | Order when showing multiple images: `"sequential"`, `"random"`, `"time_based"` (advance on a wall-clock interval), or `"date_based"` (one image per day) | -| `rotation_settings.sequential_loop` | `true` | Loop back to the first image after the last | -| `rotation_settings.random_seed` | `null` | Optional fixed seed for reproducible random order | -| `rotation_settings.time_intervals.enabled` | `false` | Tie image changes to wall-clock intervals | -| `rotation_settings.time_intervals.interval_seconds` | `3600` | Wall-clock interval when enabled | -| `image_rotation_interval` | `15` | Seconds between images during rotation | -| `fit_to_display` | `true` | Scale image to display dimensions | -| `preserve_aspect_ratio` | `true` | Don't stretch when scaling | -| `background_color` | `[0, 0, 0]` | RGB fill behind transparent pixels | -| `display_duration` | `10` | Seconds the plugin holds the screen each rotation | +The `images` array is normally filled by the upload widget in the web UI, which +writes the file and the entry for you. Each entry takes: -### Per-Image Scheduling +| Key | Type | Default | What it does | +|-----|------|---------|--------------| +| `id` | string | *auto* | Unique identifier for the entry | +| `path` | string | — | File path, relative to the project root | +| `display_order` | integer | `0` | Order for sequential rotation; lower goes first | +| `uploaded_at` | string | *auto* | Upload timestamp, set by the UI | +| `schedule` | object | `null` | Optional time window — see [Per-Image Schedules](#per-image-schedules) | -Each entry in `images` can carry an optional `schedule` so an image only shows at -certain times (e.g. a "good morning" board, or business-hours signage): +PNG, JPEG and GIF all load; PNG is the sensible choice for anything with sharp +edges or transparency. A still frame is taken from an animated GIF — this +plugin does not animate. -| Schedule key | Default | Notes | -|---|---|---| -| `schedule.enabled` | `false` | Turn scheduling on for this image | -| `schedule.mode` | `"always"` | `"always"` (any time), `"time_range"` (same window every day), or `"per_day"` (a different window per weekday) | -| `schedule.start_time` / `schedule.end_time` | `"08:00"` / `"18:00"` | Window bounds (HH:MM, 24-hour) for `time_range` mode | -| `schedule.days.` | — | Per-weekday `enabled` + `start_time`/`end_time`, used when `mode` is `"per_day"` | +--- -When several images are eligible at the same time, they rotate per -`image_config.rotation_mode`. +## Scaling and Background -## Usage +| Option | Type | Default | What it does | +|--------|------|---------|--------------| +| `fit_to_display` | boolean | `true` | Scale the image to the panel | +| `preserve_aspect_ratio` | boolean | `true` | Keep proportions while scaling | +| `background_color` | array | `[0, 0, 0]` | Fill for transparent areas, `[R, G, B]` | -### Basic Setup +### `fit_to_display` and `preserve_aspect_ratio` -1. Place your image in a directory (e.g., `assets/static_images/`) -2. Configure the plugin with the image path -3. Enable the plugin -4. The image will display automatically during rotation +![Four panels: a wide image fitted and unfitted, and with aspect ratio +preserved and stretched](../../docs/assets/static-image/fit-and-aspect.png) -### Image Guidelines +- **`fit_to_display: true`** (the default) scales the image to the panel. With + it off, the image is drawn at its native pixel size — a 192×64 source on a + 128×32 panel shows only the middle of itself. +- **`preserve_aspect_ratio: true`** (the default) keeps proportions, so a wide + image is letterboxed rather than squashed. Turn it off only when you want the + image to fill the panel exactly and do not mind the distortion. -**Recommended:** -- Use PNG format for best quality and transparency support -- Size images close to your display resolution for best performance -- For 64x32 displays: 64x32 or 128x64 images work well -- Use transparency to blend with background +The two work together: `preserve_aspect_ratio` has no effect when +`fit_to_display` is off, because nothing is being scaled. -**Supported Formats:** -- PNG (recommended for transparency) -- JPG/JPEG -- BMP -- GIF -- TIFF +**Design images at your panel's aspect ratio** where you can. A 128×32 panel is +4:1, which is unusually wide — a square logo will only ever use a third of it. -### Tips for Best Results +Choosing a format: -1. **For Logos**: Use PNG with transparent background -2. **For Photos**: Use JPG for smaller file size -3. **For Pixel Art**: Use PNG at native resolution -4. **For Icons**: Scale to exact display size +| Content | Use | Why | +|---------|-----|-----| +| Logo or icon | PNG with transparency | Sharp edges stay sharp, and the background stays unlit | +| Photograph | JPEG | Much smaller for the same result; transparency is not needed | +| Pixel art | PNG at native resolution | Sized to the panel exactly, no resampling to soften it | -## Advanced Usage +### `background_color` -### Dynamic Image Updates +Transparent pixels in a PNG are filled with this colour. -Change images programmatically via the Web UI or API: +![Four panels showing a transparent-background mark over black, navy, red and +grey](../../docs/assets/static-image/background-color.png) -```python -# Via plugin manager -plugin.set_image_path("assets/static_images/new_image.png") -plugin.reload_image() -``` +Black (the default) leaves those pixels unlit, which is what you almost always +want on an LED matrix. A non-black background lights **every** pixel on the +panel — noticeably brighter in a dark room and a real increase in power draw. -### Multiple Images +--- -Put all the images you want to cycle through into the `images` array (see -the multi-image example above) and set `image_config.mode` to -`"multiple"`. +## Rotating Through Several Images -## Troubleshooting +| Option | Type | Default | What it does | +|--------|------|---------|--------------| +| `image_config.mode` | string | `single` | `single` shows one image; `multiple` rotates | +| `image_config.rotation_mode` | string | `sequential` | How the next image is chosen | +| `rotation_settings.sequential_loop` | boolean | `true` | Return to the first image after the last | +| `rotation_settings.random_seed` | integer / null | `null` | Fixes the random order; `null` uses the clock | +| `image_rotation_interval` | number | `15` | Seconds each image is shown | +| `display_duration` | number | `10` | Seconds the plugin holds the panel per turn | + +### `rotation_mode` + +| Value | What it does | +|-------|--------------| +| `sequential` | In `display_order`, wrapping at the end when `sequential_loop` is on | +| `random` | A random pick each time. Set `random_seed` for a repeatable order | +| `time_based` | Advances on its own timer — **also needs `rotation_settings.time_intervals.enabled: true`** | +| `date_based` | **Not implemented.** The code is a stub that always returns the first image | -**Image not displaying:** -- Check that image path is correct -- Verify image file exists -- Check file permissions -- Review logs for error messages +Two of those deserve emphasis: -**Image looks distorted:** -- Enable `preserve_aspect_ratio` -- Check image dimensions vs display size -- Verify image isn't corrupted +- **`time_based` needs a second switch.** Setting `rotation_mode: "time_based"` + alone does nothing; `rotation_settings.time_intervals.enabled` must also be + `true`, and `interval_seconds` (default `3600`) sets the pace. With the switch + off, the image never advances. +- **`date_based` does nothing at all.** It is a placeholder in the source — + selecting it pins the display to the first available image. It is listed here + because the setting is offered in the UI and silently doing nothing is worse + than being told. -**Image appears cropped:** -- Enable `fit_to_display` -- Check image size matches display +With `sequential_loop: false` the rotation stops on the last image rather than +wrapping, which is what you want for a sequence with an ending. -**Transparency not working:** -- Use PNG format with alpha channel -- Verify background_color is set correctly +### The two rotation intervals -## Examples +There are two different "how often" settings and they are not alternatives: + +| Setting | Default | Applies | +|---------|---------|---------| +| `image_rotation_interval` | `15` | Always. Seconds each image is shown before the next | +| `rotation_settings.time_intervals.interval_seconds` | `3600` | **Only** in `time_based` mode, and only with `time_intervals.enabled` on | + +`image_rotation_interval` is the one most people want. It falls back to +`display_duration` if unset, so leaving both alone gives a 10-second dwell. + +--- + +## Per-Image Schedules + +Each image can carry a `schedule` object restricting when it is eligible. +Images outside their window are skipped by the rotation entirely. -### Logo Display ```json { - "enabled": true, - "images": [ - { "id": "company_logo", "path": "assets/static_images/company_logo.png" } - ], - "fit_to_display": true, - "preserve_aspect_ratio": true, - "background_color": [0, 0, 0] + "id": "open-sign", + "path": "assets/plugins/static-image/open.png", + "schedule": { + "enabled": true, + "mode": "time_range", + "start_time": "08:00", + "end_time": "18:00" + } } ``` -### Pixel Art -```json -{ - "enabled": true, - "images": [ - { "id": "pixel_art", "path": "assets/static_images/pixel_art.png" } - ], - "fit_to_display": false, - "preserve_aspect_ratio": true, - "background_color": [0, 0, 50] -} +| Key | Default | What it does | +|-----|---------|--------------| +| `enabled` | `false` | Turn scheduling on for this image. **With it off the schedule is ignored entirely** | +| `mode` | `always` | `always`, `time_range` (same window every day), or `per_day` (a different window per weekday) | +| `start_time` | `"08:00"` | Window opens, `HH:MM` 24-hour | +| `end_time` | `"18:00"` | Window closes, `HH:MM` 24-hour | +| `days` | `null` | Per-weekday windows, used only when `mode` is `per_day` | + +The common mistake is setting `mode` and the times but leaving `enabled` at +`false`, which leaves the image always visible. + +If every image is scheduled out at once there is nothing eligible to draw, so +keep at least one image unscheduled as a fallback. + +--- + +## Panel Sizes + +![The same mark on 64x32, 128x32, 128x64 and 256x32 +panels](../../docs/assets/static-image/panel-sizes.png) + +With `preserve_aspect_ratio` on, a square image is capped by the panel's +*height*, so a longer chain does not make it bigger — it just centres it in +more black. Doubling the height to 128×64 doubles the mark. If you want an +image to use a wide panel, give it a wide source. + +--- + +## Troubleshooting + +**Nothing appears.** +`enabled` defaults to `false`. After that, check the `images` array is not +empty and that at least one entry's `path` resolves. + +**The image is missing but others show.** +Check the log for a load warning. `path` is relative to the LEDMatrix project +root, not to the plugin directory. + +**Only part of the image is visible.** +`fit_to_display` is off, so the image is drawn at native size and cropped by +the panel. Turn it on, or resize the source. + +**The image looks squashed.** +`preserve_aspect_ratio` is off. Turn it on to letterbox instead of stretch. + +**It never rotates.** +Check `image_config.mode` is `multiple` — `single` never advances. If +`rotation_mode` is `time_based`, also check +`rotation_settings.time_intervals.enabled` is `true`. If it is `date_based`, +that mode is a stub and will not rotate at all. + +**A scheduled image shows all the time.** +`schedule.enabled` defaults to `false`; the window is ignored until you set it. + +**The whole panel is lit and it is too bright.** +`background_color` is not black. Transparent areas are being filled with it. + +--- + +## Development + +### Project structure + +```text +static-image/ +├── manifest.json # Plugin metadata and version history +├── manager.py # StaticImagePlugin +├── config_schema.json # Settings schema; source of truth for defaults +├── requirements.txt +├── test/ # Harness config and golden images +└── README.md ``` -### Full Screen Photo -```json -{ - "enabled": true, - "images": [ - { "id": "photo", "path": "assets/static_images/photo.jpg" } - ], - "fit_to_display": true, - "preserve_aspect_ratio": false, - "background_color": [0, 0, 0] -} +### Changing the image programmatically + +The plugin exposes two methods for driving it from code or another plugin +rather than through configuration: + +```python +plugin.set_image_path("assets/plugins/static-image/alert.png") +plugin.reload_image() ``` -## License +Both return a boolean for whether they succeeded. This bypasses the `images` +array and the rotation, so it suits a one-off takeover — an alert, say — rather +than a permanent change. + +### Regenerating the images in this README + +```bash +python scripts/render_docs_assets.py --plugin static-image +``` + +`--check` verifies the committed images still match what the plugin renders. +The sample marks live in `docs/assets/static-image/sample/`. + +Note that rotation cannot be shown in a still: every `rotation_mode` starts on +the first eligible image, and the differences only appear across frames. The +rotation behaviour above is documented from the source rather than from a +screenshot. + +--- + +## Support -GPL-3.0 License - see main LEDMatrix repository for details. +- YouTube: +- Instagram: +- Discord: +- Sponsor: [GitHub Sponsors](https://github.com/sponsors/ChuckBuilds) · + [Buy Me a Coffee](https://buymeacoffee.com/chuckbuilds) · + [Ko-fi](https://ko-fi.com/chuckbuilds/) +Released under the GNU General Public License v3.0 — see [LICENSE](LICENSE). diff --git a/plugins/static-image/manifest.json b/plugins/static-image/manifest.json index ccba68e6..85f75abf 100644 --- a/plugins/static-image/manifest.json +++ b/plugins/static-image/manifest.json @@ -1,7 +1,7 @@ { "id": "static-image", "name": "Static Image Display", - "version": "1.0.5", + "version": "1.0.6", "author": "ChuckBuilds", "description": "Display static images on your LED matrix with automatic scaling, aspect ratio preservation, and transparency support. Perfect for logos, artwork, or custom graphics.", "entry_point": "manager.py", @@ -18,6 +18,12 @@ "static_image" ], "versions": [ + { + "released": "2026-09-02", + "version": "1.0.6", + "notes": "Documentation only, no behaviour change. Rewrites the README around real rendered screenshots and documents all 23 settings including the per-image schedule object. Records two things a user would otherwise discover by staring at an unchanging panel: rotation_mode 'date_based' is a stub in the source that always returns the first image, and 'time_based' does nothing unless rotation_settings.time_intervals.enabled is also turned on. Separates the two rotation intervals that look interchangeable -- image_rotation_interval always applies, while time_intervals.interval_seconds is only read in time_based mode -- and notes that schedule.enabled defaults to false, so a configured window is ignored until it is switched on.", + "ledmatrix_min": "2.0.0" + }, { "released": "2026-07-17", "version": "1.0.5", @@ -46,7 +52,7 @@ "ledmatrix_min_version": "2.0.0" } ], - "last_updated": "2026-07-17", + "last_updated": "2026-09-02", "stars": 0, "downloads": 0, "verified": true,