diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..962b414 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,138 @@ +# Pixel Sorting Examples + +This directory contains comprehensive examples of all pixel sorting modes, sorting functions, and parameter variations. + +**Source Image:** Urban scene with person in pink/purple tones + +**Total Examples:** 31 (including original) + +--- + +## Original + +- `00_original.png` - Original unmodified image + +--- + +## Interval Modes + +Different ways to define which parts of the image get sorted: + +- `01_interval_bright.png` - **Bright mode** - Sorts pixels with brightness ≥ threshold (subtle: 109) +- `02_interval_dark.png` - **Dark mode** - Sorts pixels with brightness ≤ threshold (subtle: 33) +- `03_interval_white.png` - **White mode** - Sorts pixels with value ≥ threshold (ASDF-style) +- `04_interval_black.png` - **Black mode** - Sorts pixels with value ≤ threshold (ASDF-style) +- `05_interval_threshold.png` - **Threshold mode** - Sorts pixels between 0.3-0.7 brightness +- `06_interval_random.png` - **Random intervals** - Randomly generated intervals (char_length=80) +- `07_interval_waves.png` - **Wave intervals** - Uniform wave-like intervals (char_length=60) +- `08_interval_edges.png` - **Edge detection** - Intervals defined by edge detection +- `09_interval_none.png` - **No intervals** - Sorts entire rows without boundaries + +--- + +## Sorting Functions + +Different ways to sort pixels within intervals (all using bright mode): + +- `10_sort_lightness.png` - **Lightness** - Sort by brightness (HLS lightness) +- `11_sort_hue.png` - **Hue** - Sort by color hue (creates rainbow effects) +- `12_sort_saturation.png` - **Saturation** - Sort by color saturation intensity +- `13_sort_intensity.png` - **Intensity** - Sort by sum of RGB values +- `14_sort_minimum.png` - **Minimum** - Sort by minimum RGB channel value +- `15_sort_value.png` - **Value** - Sort by pixel integer value (ASDF original) + +--- + +## Angle Variations + +Diagonal and vertical sorting effects: + +- `16_angle_45.png` - **45° diagonal** - Diagonal sorting at 45 degrees +- `17_angle_90.png` - **90° vertical** - Vertical sorting (perpendicular to default) +- `18_angle_-45.png` - **-45° diagonal** - Diagonal sorting in opposite direction + +--- + +## Randomness + +Skip some intervals randomly for variation: + +- `19_randomness_25.png` - **25% random skip** - Randomly skip 25% of intervals +- `20_randomness_50.png` - **50% random skip** - Half of intervals left unsorted +- `21_randomness_75.png` - **75% random skip** - Most intervals skipped (with random mode) + +--- + +## Multiple Passes + +Apply sorting multiple times: + +- `22_loops_2.png` - **2 passes** - Sort the image twice +- `23_loops_3.png` - **3 passes** - Sort the image three times (stronger effect) + +--- + +## Creative Combinations + +Complex effects combining multiple parameters: + +- `24_combo_random_hue.png` - **Random + Hue + 20% randomness** + - Interval: random (char_length=100) + - Sorting: hue + - Randomness: 20% + +- `25_combo_edges_saturation.png` - **Edge detection + Saturation** + - Interval: edges (lower_threshold=0.3) + - Sorting: saturation + +- `26_combo_waves_hue.png` - **Waves + Hue** + - Interval: waves (char_length=50) + - Sorting: hue + +- `27_combo_diagonal_random_hue.png` - **Diagonal + Random + Hue** + - Interval: random (char_length=80) + - Sorting: hue + - Angle: 45° + +- `28_combo_dark_lightness_loops.png` - **Dark + Lightness + Multiple passes** + - Interval: dark (subtle threshold) + - Sorting: lightness + - Loops: 2 + +- `29_combo_bright_saturation_90.png` - **Bright + Saturation + Vertical** + - Interval: bright (subtle threshold) + - Sorting: saturation + - Angle: 90° + +- `30_combo_threshold_hue_rand.png` - **Threshold + Hue + Randomness** + - Interval: threshold (0.2-0.8) + - Sorting: hue + - Randomness: 30% + +--- + +## Analysis Results + +For this image, the analysis suggested: + +**Brightness thresholds:** +- Bright (subtle): 109 +- Dark (subtle): 33 + +These values were used for the examples to ensure good results for this specific image. + +--- + +## Regenerating Examples + +To regenerate all examples with a different image: + +```bash +# Edit generate_examples.py to point to your image +uv run python generate_examples.py +``` + +The script automatically: +1. Analyzes the image to find optimal thresholds +2. Generates examples for all modes +3. Creates organized, numbered output files diff --git a/generate_examples.py b/generate_examples.py new file mode 100644 index 0000000..89a348b --- /dev/null +++ b/generate_examples.py @@ -0,0 +1,193 @@ +"""Generate comprehensive examples for all pixel sorting modes and settings.""" + +from PIL import Image +from pixelsort import pixelsort, analyze +from pathlib import Path + +# Input image (Change this to make a new examples) +input_path = "/home/rockerboo/art/boo-2025/c-f1-2025-10-22_00031_.png" + +img = Image.open(input_path) + +# Create examples directory +examples_dir = Path("examples") +examples_dir.mkdir(exist_ok=True) + +# Save original +print("Saving original...") +img.save(examples_dir / "00_original.png") + +# Analyze image first +print("Analyzing image...") +stats = analyze(img) +print(f"Suggested bright (subtle): {stats['suggestions']['bright']['subtle']}") +print(f"Suggested dark (subtle): {stats['suggestions']['dark']['subtle']}") +print() + +# Track all examples +example_count = 1 + +def save_example(result, name, description): + """Save an example with a numbered prefix.""" + global example_count + filename = f"{example_count:02d}_{name}.png" + result.save(examples_dir / filename) + print(f"[{example_count:02d}] {description}") + example_count += 1 + return filename + +print("=" * 60) +print("INTERVAL MODES (with default sorting=value)") +print("=" * 60) + +# Bright mode +result = pixelsort(img, interval='bright', bright_value=stats['suggestions']['bright']['subtle']) +save_example(result, "interval_bright", "Bright mode (subtle threshold)") + +# Dark mode +result = pixelsort(img, interval='dark', dark_value=stats['suggestions']['dark']['subtle']) +save_example(result, "interval_dark", "Dark mode (subtle threshold)") + +# White mode +result = pixelsort(img, interval='white', white_value=stats['suggestions']['white']['subtle']) +save_example(result, "interval_white", "White mode (subtle threshold)") + +# Black mode +result = pixelsort(img, interval='black', black_value=stats['suggestions']['black']['subtle']) +save_example(result, "interval_black", "Black mode (subtle threshold)") + +# Threshold mode +result = pixelsort(img, interval='threshold', lower_threshold=0.3, upper_threshold=0.7) +save_example(result, "interval_threshold", "Threshold mode (0.3-0.7)") + +# Random mode +result = pixelsort(img, interval='random', char_length=80) +save_example(result, "interval_random", "Random intervals (char_length=80)") + +# Waves mode +result = pixelsort(img, interval='waves', char_length=60) +save_example(result, "interval_waves", "Wave intervals (char_length=60)") + +# Edges mode +result = pixelsort(img, interval='edges', lower_threshold=0.25) +save_example(result, "interval_edges", "Edge detection intervals") + +# None mode (sort entire rows) +result = pixelsort(img, interval='none') +save_example(result, "interval_none", "No intervals (full row sorting)") + +print() +print("=" * 60) +print("SORTING FUNCTIONS (with interval=bright)") +print("=" * 60) + +bright_val = stats['suggestions']['bright']['subtle'] + +# Lightness +result = pixelsort(img, interval='bright', sorting='lightness', bright_value=bright_val) +save_example(result, "sort_lightness", "Sort by lightness") + +# Hue +result = pixelsort(img, interval='bright', sorting='hue', bright_value=bright_val) +save_example(result, "sort_hue", "Sort by hue (rainbow effect)") + +# Saturation +result = pixelsort(img, interval='bright', sorting='saturation', bright_value=bright_val) +save_example(result, "sort_saturation", "Sort by saturation") + +# Intensity +result = pixelsort(img, interval='bright', sorting='intensity', bright_value=bright_val) +save_example(result, "sort_intensity", "Sort by intensity (RGB sum)") + +# Minimum +result = pixelsort(img, interval='bright', sorting='minimum', bright_value=bright_val) +save_example(result, "sort_minimum", "Sort by minimum RGB value") + +# Value (default) +result = pixelsort(img, interval='bright', sorting='value', bright_value=bright_val) +save_example(result, "sort_value", "Sort by pixel value (ASDF style)") + +print() +print("=" * 60) +print("ANGLE VARIATIONS") +print("=" * 60) + +# 45 degrees +result = pixelsort(img, interval='bright', angle=45, bright_value=bright_val) +save_example(result, "angle_45", "Diagonal sorting (45°)") + +# 90 degrees (vertical) +result = pixelsort(img, interval='bright', angle=90, bright_value=bright_val) +save_example(result, "angle_90", "Vertical sorting (90°)") + +# -45 degrees +result = pixelsort(img, interval='bright', angle=-45, bright_value=bright_val) +save_example(result, "angle_-45", "Diagonal sorting (-45°)") + +print() +print("=" * 60) +print("RANDOMNESS VARIATIONS") +print("=" * 60) + +# 25% randomness +result = pixelsort(img, interval='bright', randomness=25, bright_value=bright_val) +save_example(result, "randomness_25", "25% randomness (skip some intervals)") + +# 50% randomness +result = pixelsort(img, interval='bright', randomness=50, bright_value=bright_val) +save_example(result, "randomness_50", "50% randomness") + +# 75% randomness +result = pixelsort(img, interval='random', randomness=75, char_length=80) +save_example(result, "randomness_75", "75% randomness with random intervals") + +print() +print("=" * 60) +print("MULTIPLE PASSES") +print("=" * 60) + +# 2 passes +result = pixelsort(img, interval='bright', loops=2, bright_value=bright_val) +save_example(result, "loops_2", "2 passes (loops=2)") + +# 3 passes +result = pixelsort(img, interval='bright', loops=3, bright_value=bright_val) +save_example(result, "loops_3", "3 passes (loops=3)") + +print() +print("=" * 60) +print("CREATIVE COMBINATIONS") +print("=" * 60) + +# Random + Hue + Randomness +result = pixelsort(img, interval='random', sorting='hue', char_length=100, randomness=20) +save_example(result, "combo_random_hue", "Random intervals + Hue sorting + 20% randomness") + +# Edges + Saturation +result = pixelsort(img, interval='edges', sorting='saturation', lower_threshold=0.3) +save_example(result, "combo_edges_saturation", "Edge intervals + Saturation sorting") + +# Waves + Hue +result = pixelsort(img, interval='waves', sorting='hue', char_length=50) +save_example(result, "combo_waves_hue", "Wave intervals + Hue sorting") + +# Diagonal + Random + Hue +result = pixelsort(img, interval='random', sorting='hue', angle=45, char_length=80) +save_example(result, "combo_diagonal_random_hue", "45° + Random intervals + Hue sorting") + +# Dark + Lightness + Multiple passes +result = pixelsort(img, interval='dark', sorting='lightness', loops=2, dark_value=stats['suggestions']['dark']['subtle']) +save_example(result, "combo_dark_lightness_loops", "Dark mode + Lightness + 2 passes") + +# Bright + Saturation + Angle +result = pixelsort(img, interval='bright', sorting='saturation', angle=90, bright_value=bright_val) +save_example(result, "combo_bright_saturation_90", "Bright + Saturation + 90° (vertical)") + +# Threshold + Hue + Randomness +result = pixelsort(img, interval='threshold', sorting='hue', randomness=30, lower_threshold=0.2, upper_threshold=0.8) +save_example(result, "combo_threshold_hue_rand", "Threshold + Hue + 30% randomness") + +print() +print("=" * 60) +print(f"Generated {example_count - 1} examples in {examples_dir}/") +print("=" * 60)