3.8 KiB
Display Orientation
Purpose
Allow the user to configure the physical orientation of the Inky Impression display so that images are displayed upright regardless of how the panel is mounted. The orientation setting also drives the Unsplash orientation filter so fetched photos match the display's effective aspect ratio (portrait vs. landscape).
Configuration
A new display.orientation key (integer, degrees clockwise) in
config.yaml / DEFAULT_CONFIG:
display:
orientation: 0 # 0, 90, 180, 270
| Value | Unsplash filter | Effective aspect |
|---|---|---|
| 0 | landscape | width > height |
| 90 | portrait | height > width |
| 180 | landscape | width > height |
| 270 | portrait | height > width |
The old unsplash.orientation config key is no longer used by
refresh() — orientation is now derived from display.orientation +
display.resolution.
Image Processing Pipeline
- Fetch raw photo from Unsplash (with orientation filter already matching the effective aspect ratio — see below).
process_image()inInkyDisplay:- Compute effective width/height by swapping physical dimensions when orientation is 90° or 270°.
- Crop to effective aspect ratio.
- Resize to effective dimensions.
- Rotate by
-orientationdegrees (so the result matches the physical resolution of the display panel).
show()sends the processed (and rotated) image toinky.set_image(). No additional transformation is needed — the panel hardware always expects its nativewidth × heightpixel grid.
Unsplash Filter Derivation
In cli.py:refresh(), after reading display.orientation and
display.resolution:
- If orientation is 90 or 270, swap width ↔ height to get effective dimensions.
- If effective height > effective width → request
"portrait". - If effective width > effective height → request
"landscape". - If roughly equal → request
"squarish".
This means the Unsplash API is sent orientation=portrait when the display is
mounted vertically, which returns taller photos that need less cropping.
Hot-Reload
_reload_config() in cli.py detects changes to
display.orientation and updates display.orientation live. The next
process_image() call uses the new orientation. No display loop restart is
needed.
Library Caching
_save_to_library() passes the effective width/height to
save_unsplash_image() (swapped when orientation is 90/270). The stored image
is processed to the effective dimensions at orientation=0 (no rotation). This
keeps library images in their "natural" viewing orientation.
The preview endpoint (/api/preview/<id>) creates an InkyDisplay with the
current orientation, so the preview matches what the physical display shows.
UI
Settings page (Display article) shows a <select> with four options:
- 0° (Landscape)
- 90° (Portrait)
- 180° (Landscape)
- 270° (Portrait)
Saved via the existing PUT /api/config/display/orientation route.
The old unsplash.orientation dropdown has been removed from the settings
page — it is now auto-derived from the display orientation.
Edge Cases
- 0° (default): No rotation applied. Preserves existing behavior.
- 180°: Image is cropped/resized at physical dimensions, then rotated upside-down. No dimension swap. Useful for ceiling-mounted displays.
- 90° / 270°: Width and height are swapped for cropping/resizing, then rotated back to physical dimensions. Images fetched from Unsplash with the matching portrait/landscape filter.
- Preview: Shows the rotated image so the user sees exactly what the display will show.
- rotate(expand=True): Only used with 90° multiples so no fractional pixels appear.