A web-based digital photo frame application designed for e-ink displays, featuring intelligent image cropping, slideshow functionality, an## 🐛 Development Mode
The application supports development mode for testing without physical e-ink hardware:
Create a .env file in the project root to control the environment:
# Development mode (shows dev banner, no hardware access)
ENVIRONMENT=development
# or
ENVIRONMENT=dev
# Production mode (attempts hardware access)
ENVIRONMENT=production- Automatic detection when Inky library is unavailable
- Console logging instead of display output
- Full web interface functionality preserved
- Dev mode banner displayed in web interface
- No hardware requirements for testing
The application uses python-dotenv to load environment variables from the .env file. The dev mode determination is consistent across:
- Web interface dev mode banner
- Hardware detection and simulation
- Display worker behavioruitive web interface for managing your photo collection.
Main interface showing image gallery with edit controls

Drag-and-drop crop tool with aspect ratio locking
Responsive design works on all devices
- E-Ink Display Support: Optimized for e-paper displays with proper image rendering
- Web Interface: Modern, responsive web UI for managing images remotely
- Smart Cropping: Visual crop editor with aspect ratio locking to display dimensions
- Slideshow Mode: Automatic image rotation with configurable timing
- Multi-Image Upload: Bulk upload support for efficient photo management
- Drag & Drop Crop Tool: Intuitive visual cropping with real-time preview
- Metadata Editing: Add titles and descriptions to your images
- Image Controls: Enable/disable, display instantly, or delete images
- Usage Tracking: See how many times each image has been displayed
- Thumbnail Generation: Automatic thumbnail creation for fast browsing
- Developer Mode: Test without physical e-ink display
- Dual Rendering Modes: Choose between crop-to-fill or letterbox (preserve aspect ratio)
- Aspect Ratio Preservation: Optional letterboxing to maintain original image proportions
- Cache Busting: Automatic image refresh for immediate visual feedback
- Mobile Responsive: Works seamlessly on phones, tablets, and desktops
- Raspberry Pi running Raspbian/Raspberry Pi OS
- Python 3.8+ (usually pre-installed)
- Pimoroni Inky e-paper display (optional for development)
Option 1: Automated Installation (Recommended)
git clone https://github.com/ryanlane/epaper-image-frame.git
cd epaper-image-frame
./install.shThe installation script will:
- ✅ Check Python version compatibility
- ✅ Create a virtual environment
- ✅ Install all dependencies
- ✅ Set up the database
- ✅ Create necessary directories
- ✅ Configure development environment
Option 2: Manual Installation
-
Clone the repository
git clone https://github.com/ryanlane/epaper-image-frame.git cd epaper-image-frame -
Install dependencies
pip install -r requirements.txt
-
Configure environment (create
.envfile)echo "ENVIRONMENT=development" > .env
-
Initialize the database
python migrate_db.py
-
Run any additional migrations (if upgrading from an older version)
python migrate_aspect_ratio.py
-
Start the application
python app.py
-
Access the web interface Open your browser to
http://localhost:8080
epaper-image-frame/
├── app.py # Main FastAPI application
├── database.py # Database configuration and setup
├── models.py # SQLAlchemy database models
├── migrate_db.py # Initial database migration script
├── migrate_aspect_ratio.py # Aspect ratio feature migration script
├── cleanup_images.py # Development tool for removing all images
├── install.sh # Installation script for Raspberry Pi
├── .env # Environment configuration (create this file)
├── requirements.txt # Python dependencies
├── photo_frame.db # SQLite database (created automatically)
├── static/
│ ├── css/ # Stylesheets
│ ├── uploads/ # Full-size uploaded images
│ ├── thumbs/ # Generated thumbnails
│ └── current.jpg # Currently displayed image
├── templates/ # Jinja2 HTML templates
│ └── partials/ # Reusable template components
└── utils/
├── eframe_inky.py # E-ink display interface
└── image_utils.py # Image processing utilities
- Click "Upload Images" in the navigation
- Select multiple images or drag & drop
- Images are automatically processed and thumbnails generated
- Click the ✏️ Edit button on any image card
- Modify title and description as needed
- Choose display mode: Check/uncheck "Preserve original aspect ratio"
- Unchecked (Default): Crop-to-fill mode - image fills entire display
- Checked: Letterbox mode - maintains aspect ratio with black borders
- Click "Crop Settings ▼" to expand the crop editor (disabled in letterbox mode)
- Drag the orange rectangle to select the crop area
- Resize using the corner handles (aspect ratio locked to display)
- Click "Save" to apply changes
▶️ Play Now: Immediately display the image on the e-ink screen- 🖼️/🚫 Toggle: Enable/disable images in slideshow rotation
- 🗑️ Delete: Remove image from collection
- Resolution: Set your e-ink display dimensions (e.g., "800,480")
- Image Root: Directory for full-size images
- Thumb Root: Directory for thumbnails
- Slideshow: Configure automatic image rotation timing
- Backend: FastAPI (Python web framework)
- Database: SQLite with SQLAlchemy ORM
- Frontend: HTML5, CSS3, Vanilla JavaScript
- Image Processing: Pillow (PIL) for resizing and cropping
- Templates: Jinja2 templating engine
- Images: Stores image metadata, crop settings, aspect ratio preferences, and usage statistics
- Settings: Stores application configuration and display parameters
- Upload: Multi-file upload with validation
- Processing: Automatic thumbnail generation
- Storage: Organized file system with unique filenames
- Rendering: Dual-mode rendering (crop-to-fill or letterbox with aspect ratio preservation)
- Display: E-ink optimized output with configurable display modes
The advanced cropping system ensures your images always look perfect on your e-ink display:
- Dual Display Modes: Choose between crop-to-fill or letterbox rendering per image
- Aspect Ratio Locking: Crop selections automatically maintain your display's aspect ratio
- Visual Editor: Drag and resize the crop area with real-time preview
- Percentage-Based: Crop coordinates stored as percentages for resolution independence
- Smart Defaults: New images default to full-frame (0%, 0%, 100%, 100%)
- Dynamic Controls: Crop editor automatically disabled when letterbox mode is selected
The application includes migration scripts to update your database schema when upgrading:
migrate_db.py: Creates the initial database and adds crop functionality- Adds
crop_x,crop_y,crop_width,crop_heightcolumns to images table - Sets default values for full-frame cropping (0, 0, 100, 100)
- Adds
migrate_aspect_ratio.py: Adds aspect ratio preservation feature- Adds
preserve_aspect_ratioboolean column to images table - Defaults to
FALSE(crop-to-fill behavior) for existing images
- Adds
# For new installations
python migrate_db.py
# For upgrades (run only if needed)
python migrate_aspect_ratio.pyNote: Migration scripts are safe to run multiple times - they check for existing columns before making changes.
The application offers two rendering modes for different image display preferences:
- Behavior: Image is cropped to completely fill the display
- Pros: No black borders, full screen utilization
- Cons: Some image content may be cropped out
- Best for: Landscape photos, images shot at similar aspect ratio to display
- Behavior: Image maintains original proportions with black borders if needed
- Pros: Shows complete image content, preserves photographer's intent
- Cons: May have black bars on sides or top/bottom
- Best for: Portrait photos, artwork, images with important edge content
Each image can be individually configured:
- Edit the image
- Toggle "Preserve original aspect ratio" checkbox
- Save changes
- Crop controls are automatically disabled in letterbox mode
- Automatic Rotation: Configure timing for hands-free operation
- Smart Selection: Only enabled images participate in slideshow
- Manual Override: "Play Now" button for immediate display
- Usage Tracking: Monitor which images are displayed most frequently
The project includes several utility scripts for development and maintenance:
migrate_db.py: Initial database setup with crop functionalitymigrate_aspect_ratio.py: Adds aspect ratio preservation feature
The cleanup_images.py script helps developers reset the image collection during testing:
# Check current status (non-destructive)
python3 cleanup_images.py --status
# Interactive cleanup with confirmation
python3 cleanup_images.py
# Show help
python3 cleanup_images.py --helpFeatures:
- Safe by default: Multiple confirmation prompts before deletion
- Comprehensive reporting: Shows exactly what will be removed
- Status checking: Non-destructive status reports
- Complete cleanup: Removes database records AND files
- Development focused: Perfect for testing and fresh starts
What it removes:
- All image records from the database
- All files in the uploads directory
- All files in the thumbnails directory
- The current display image (
static/current.jpg)
--status first to review what will be deleted.
For development and testing without physical e-ink hardware:
- Automatic detection when Inky library is unavailable
- Console logging instead of display output
- Full web interface functionality preserved
- Banner notification of developer mode status
The responsive design works seamlessly across devices:
- Mobile: Touch-friendly interface with collapsible navigation
- Tablet: Optimized layout for medium screens
- Desktop: Full-featured experience with keyboard shortcuts
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built for e-ink displays, particularly Inky series
- Inspired by the need for elegant, low-power digital photo frames
- Community contributions welcome!
