This commit is contained in:
Andras Schmelczer 2026-03-30 08:09:47 +01:00
commit 36d975545b
38 changed files with 2837 additions and 0 deletions

164
dither_test/README.md Normal file
View file

@ -0,0 +1,164 @@
# Dithering Test Suite
Local testing suite for comparing dithering algorithms on the 6-color e-ink display.
## Setup
```bash
cd dither_test
pip install pillow numpy
```
For the interactive preview (optional):
```bash
# Tkinter is usually included with Python
# On Debian/Ubuntu if missing:
sudo apt-get install python3-tk
```
## Quick Start
### Compare all algorithms
```bash
python compare.py photo.jpg --html
# Open dither_output/photo_report.html in browser
```
### Interactive preview
```bash
python preview.py photo.jpg
# Use arrow keys to cycle through algorithms
```
## Tools
### `compare.py` - Batch Comparison Tool
Generate comparison outputs for multiple dithering algorithms.
```bash
# Compare all algorithms, save individual images
python compare.py image.jpg
# Compare specific algorithms only
python compare.py image.jpg -a floyd_steinberg atkinson jarvis
# Generate visual grid comparison
python compare.py image.jpg --grid
# Generate HTML report (recommended)
python compare.py image.jpg --html
# Side-by-side comparison of two algorithms
python compare.py image.jpg --side-by-side atkinson pil_fs
# With rotation
python compare.py image.jpg --html -r 90
# List available algorithms
python compare.py --list
```
### `preview.py` - Interactive Preview
Real-time preview with keyboard navigation.
```bash
python preview.py image.jpg
```
**Keyboard shortcuts:**
- `←` / `→` or `A` / `D` - Cycle through algorithms
- `R` - Rotate image (0° → 90° → 180° → 270°)
- `S` - Save current result
- `O` - Open new image
- `Q` or `Esc` - Quit
### `dither_algorithms.py` - Algorithm Library
Use in your own scripts:
```python
from dither_algorithms import apply_dithering, get_algorithm_names
from PIL import Image
img = Image.open('photo.jpg')
dithered = apply_dithering(img, 'atkinson')
dithered.save('output.png')
# List all algorithms
print(get_algorithm_names())
```
## Available Algorithms
### Error Diffusion (spread quantization error to neighbors)
| Algorithm | Description |
|-----------|-------------|
| `floyd_steinberg` | Classic (1976), good balance of speed and quality |
| `floyd_steinberg_weighted` | With perceptual color weighting |
| `atkinson` | Bill Atkinson (Apple), cleaner with 75% error diffusion |
| `atkinson_weighted` | Atkinson with perceptual weighting |
| `jarvis` | Jarvis-Judice-Ninke, smoother gradients, slower |
| `stucki` | Similar to JJN with modified weights |
| `sierra` | Full Sierra, balanced results |
| `sierra_lite` | Faster Sierra variant |
| `burkes` | Simplified two-row diffusion |
### Ordered Dithering (threshold matrix pattern)
| Algorithm | Description |
|-----------|-------------|
| `bayer2` | 2×2 Bayer matrix, visible pattern |
| `bayer4` | 4×4 Bayer matrix, common choice |
| `bayer8` | 8×8 Bayer matrix, finer pattern |
| `bayer4_strong` | 4×4 with increased strength |
### PIL Built-in (for reference)
| Algorithm | Description |
|-----------|-------------|
| `none` | No dithering, nearest color only |
| `pil_fs` | PIL's Floyd-Steinberg implementation |
## Recommendations
For **photographic images**: `atkinson` or `floyd_steinberg_weighted`
- Better color accuracy, smoother gradients
For **graphics/illustrations**: `bayer4` or `bayer8`
- Consistent patterns, no "wormy" artifacts
For **high contrast images**: `atkinson`
- Cleaner edges, less noise in solid areas
For **fastest processing**: `sierra_lite` or `pil_fs`
- Good quality with faster execution
## Output
Results are saved to `dither_output/` by default:
```
dither_output/
├── photo_source.png # Prepared source (800×480)
├── photo_atkinson.png # Each algorithm result
├── photo_floyd_steinberg.png
├── ...
├── photo_grid.png # Grid comparison (--grid)
└── photo_report.html # HTML report (--html)
```
## 6-Color Palette
The e-ink display uses these colors:
| Color | RGB |
|--------|-----|
| Black | (0, 0, 0) |
| White | (255, 255, 255) |
| Yellow | (255, 255, 0) |
| Red | (255, 0, 0) |
| Blue | (0, 0, 255) |
| Green | (0, 255, 0) |