mirror of
https://github.com/dredx/prole.git
synced 2026-09-23 12:03:59 +00:00
262 lines
6.6 KiB
Markdown
262 lines
6.6 KiB
Markdown
# Image Resource Management
|
|
|
|
## Overview
|
|
|
|
The Knoe Database Installer includes multiple image assets that need to work both when running from source and when packaged as a standalone binary. This document explains how image resources are managed.
|
|
|
|
## Image Assets
|
|
|
|
The following images are included in the installer:
|
|
|
|
### Primary Assets
|
|
- **knoeIcon.png** (1,494,782 bytes) - Application icon
|
|
- **knoeLogo.png** (2,190,703 bytes) - Main Knoe logo
|
|
- **knoeLogoSepia.png** (2,657,956 bytes) - Sepia-toned background logo
|
|
- **knoeLogoBlueprint.png** (3,107,147 bytes) - Blueprint style logo
|
|
- **knoeIconblueprint.png** (1,570,109 bytes) - Blueprint style icon
|
|
|
|
### Supplementary Assets
|
|
- **knoe-type.gif** (599 bytes) - Small typing animation
|
|
|
|
## Resource Path Resolution
|
|
|
|
### The Challenge
|
|
|
|
When packaging Python applications with PyInstaller, resource files need to be found in two different scenarios:
|
|
1. **Development**: Running from source, files are in `PROJECT_ROOT/img/`
|
|
2. **Production**: Running from bundle, files are in PyInstaller's temporary extraction directory
|
|
|
|
### The Solution
|
|
|
|
The `get_resource_path()` function automatically resolves paths correctly in both scenarios:
|
|
|
|
```python
|
|
def get_resource_path(relative_path):
|
|
"""Get absolute path to resource, works for dev and for PyInstaller."""
|
|
try:
|
|
# PyInstaller creates a temp folder and stores path in _MEIPASS
|
|
base_path = Path(sys._MEIPASS)
|
|
except AttributeError:
|
|
# Running from source
|
|
base_path = PROJECT_ROOT
|
|
|
|
return base_path / relative_path
|
|
```
|
|
|
|
### Usage
|
|
|
|
All image loading code uses this function:
|
|
|
|
```python
|
|
# Instead of:
|
|
bg_path = Path('img/knoeLogoSepia.png')
|
|
|
|
# Use:
|
|
bg_path = get_resource_path('img/knoeLogoSepia.png')
|
|
```
|
|
|
|
## Implementation Details
|
|
|
|
### Modified Code Locations
|
|
|
|
The following locations in `install.py` were updated to use `get_resource_path()`:
|
|
|
|
1. **Background logo loading** (line ~191)
|
|
```python
|
|
bg_path = get_resource_path('img/knoeLogoSepia.png')
|
|
```
|
|
|
|
2. **Application icon candidates** (line ~406)
|
|
```python
|
|
img_candidates = [
|
|
get_resource_path('img/knoeIcon.png'),
|
|
get_resource_path('img/knoe-type.png'),
|
|
get_resource_path('img/knoe-type.gif'),
|
|
get_resource_path('img/Knoe.png'),
|
|
get_resource_path('img/knoeLogoSepia.png'),
|
|
]
|
|
```
|
|
|
|
3. **DMG background image** (line ~3820)
|
|
```python
|
|
bg_img = get_resource_path('img/knoeLogoSepia.png')
|
|
```
|
|
|
|
### PyInstaller Configuration
|
|
|
|
The `installer.spec` file includes the entire `img/` directory in the bundle:
|
|
|
|
```python
|
|
datas = [
|
|
('installer', 'installer'),
|
|
('conf', 'conf'),
|
|
('etc', 'etc'),
|
|
('img', 'img'), # All images included
|
|
('docs', 'docs'),
|
|
]
|
|
```
|
|
|
|
This ensures all images are:
|
|
1. Copied into the PyInstaller bundle
|
|
2. Extracted to the temporary directory at runtime
|
|
3. Accessible via `sys._MEIPASS / 'img' / filename`
|
|
|
|
## Testing
|
|
|
|
### Verify Resource Paths
|
|
|
|
Run the test script:
|
|
|
|
```bash
|
|
python3 test_resource_paths.py
|
|
```
|
|
|
|
This tests:
|
|
- Path resolution from source
|
|
- Path resolution simulating PyInstaller environment
|
|
- Existence of all image files
|
|
|
|
Expected output:
|
|
```
|
|
✓ App icon
|
|
✓ Background logo (sepia)
|
|
✓ Main logo
|
|
✓ Blueprint logo
|
|
✓ Blueprint icon
|
|
|
|
✓ All tests passed!
|
|
Images will be correctly included in PyInstaller build.
|
|
```
|
|
|
|
### Manual Testing
|
|
|
|
From source:
|
|
```bash
|
|
python3 install.py --gui
|
|
# Check that logo appears in background
|
|
```
|
|
|
|
From built binary:
|
|
```bash
|
|
make package
|
|
./dist/Knoe\ Installer.app/Contents/MacOS/knoe-installer --gui
|
|
# Check that logo appears in background
|
|
```
|
|
|
|
## Icon Formats
|
|
|
|
### PNG (Source)
|
|
- Format: PNG with transparency
|
|
- Resolution: 1024x1024 recommended
|
|
- Location: `img/knoeIcon.png`
|
|
|
|
### ICNS (macOS Bundle)
|
|
- Generated by build system from PNG
|
|
- Contains multiple resolutions (16x16 through 1024x1024)
|
|
- Location: `build/knoe.icns` (intermediate), embedded in `.app` bundle
|
|
- Generated by: `make build/knoe.icns`
|
|
|
|
The build system automatically converts PNG to ICNS using macOS tools:
|
|
```bash
|
|
sips -z 512 512 img/knoeIcon.png --out build/icon.iconset/icon_512x512.png
|
|
iconutil -c icns build/icon.iconset -o build/knoe.icns
|
|
```
|
|
|
|
## Background Image Usage
|
|
|
|
The GUI installer uses `knoeLogoSepia.png` as a subtle background:
|
|
|
|
1. **Loading**: Image loaded via PIL (Pillow)
|
|
2. **Processing**:
|
|
- Converted to RGBA
|
|
- Blended with white background at 15% opacity
|
|
- Creates subtle watermark effect
|
|
3. **Rendering**:
|
|
- Scaled to fill canvas
|
|
- Maintains aspect ratio
|
|
- Centered on canvas
|
|
|
|
Code snippet:
|
|
```python
|
|
bg_path = get_resource_path('img/knoeLogoSepia.png')
|
|
if bg_path.exists():
|
|
original = Image.open(str(bg_path)).convert('RGBA')
|
|
white_bg = Image.new('RGBA', original.size, (255, 255, 255, 255))
|
|
self._bg_pil = Image.blend(white_bg, original, 0.15)
|
|
```
|
|
|
|
## Adding New Images
|
|
|
|
To add new image resources:
|
|
|
|
1. **Add image file** to `img/` directory
|
|
2. **Update code** to use `get_resource_path()`:
|
|
```python
|
|
new_img = get_resource_path('img/new_image.png')
|
|
```
|
|
3. **No spec changes needed** - entire `img/` directory is already included
|
|
4. **Test** with `python3 test_resource_paths.py`
|
|
|
|
## Troubleshooting
|
|
|
|
### Image Not Found in Built Binary
|
|
|
|
**Symptom:** Image loads from source but not from built `.app`
|
|
|
|
**Cause:** Path hardcoded instead of using `get_resource_path()`
|
|
|
|
**Solution:**
|
|
```python
|
|
# Wrong:
|
|
img_path = PROJECT_ROOT / 'img' / 'logo.png'
|
|
|
|
# Correct:
|
|
img_path = get_resource_path('img/logo.png')
|
|
```
|
|
|
|
### Image Not Showing in GUI
|
|
|
|
**Cause:** File doesn't exist or wrong path
|
|
|
|
**Solution:** Check with test script:
|
|
```bash
|
|
python3 test_resource_paths.py
|
|
```
|
|
|
|
### Build Size Too Large
|
|
|
|
**Cause:** Large images included in bundle
|
|
|
|
**Solution:**
|
|
- Optimize PNG files: `pngcrush`, `optipng`, etc.
|
|
- Consider JPEG for photos (PNG for logos/icons)
|
|
- Remove unused images from `img/` directory
|
|
|
|
## Performance Considerations
|
|
|
|
### Startup Time
|
|
|
|
PyInstaller extracts bundled resources to a temporary directory on each launch:
|
|
- **Small images** (< 100 KB): Negligible impact
|
|
- **Large images** (> 1 MB): 100-200ms extraction time
|
|
- **Total time**: ~1-2 seconds for all resources
|
|
|
|
### Memory Usage
|
|
|
|
Images are loaded into memory when displayed:
|
|
- **knoeLogoSepia.png**: ~2.6 MB on disk, ~10 MB in memory (RGBA)
|
|
- **Scaled versions**: Additional memory for display size
|
|
|
|
### Optimization
|
|
|
|
For production, consider:
|
|
1. Compress images before including
|
|
2. Use lazy loading (load only when needed)
|
|
3. Cache scaled versions instead of re-scaling
|
|
|
|
## References
|
|
|
|
- [PyInstaller Data Files](https://pyinstaller.org/en/stable/spec-files.html#adding-data-files)
|
|
- [Pillow (PIL) Documentation](https://pillow.readthedocs.io/)
|
|
- [macOS Icon Creation](https://developer.apple.com/design/human-interface-guidelines/app-icons)
|