1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//! Simple image rendering example with automatic resize handling
//!
//! This example demonstrates how to render an image to braille with automatic
//! re-rendering when the terminal window is resized. The image will scale
//! appropriately to fit the new terminal dimensions while maintaining aspect ratio.
//!
//! # Controls
//!
//! - **Q or Esc**: Quit
//! - Terminal resize will automatically trigger re-render
//!
//! # Usage
//!
//! ```bash
//! cargo run --example simple_image --features image
//! ```
use crossterm::event::{self, Event, KeyCode, KeyEvent};
use crossterm::terminal::{self, ClearType};
use crossterm::{cursor, execute};
use dotmax::image::render_image_simple;
use dotmax::TerminalRenderer;
use std::io::{self, Write};
use std::path::Path;
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Path to the image we'll render
let image_path = Path::new("tests/fixtures/images/sample.png");
// Enable raw mode for event handling
terminal::enable_raw_mode()?;
// Initial render
render_image(image_path)?;
// Event loop for resize handling and quit
loop {
// Poll for events with 100ms timeout
if event::poll(Duration::from_millis(100))? {
match event::read()? {
// Handle terminal resize events
Event::Resize(width, height) => {
tracing::info!("Terminal resized to {}x{}", width, height);
render_image(image_path)?;
}
// Handle quit keys (Q or Esc)
Event::Key(KeyEvent {
code: KeyCode::Char('q' | 'Q') | KeyCode::Esc,
..
}) => {
break;
}
// Ignore other events
_ => {}
}
}
}
// Cleanup: disable raw mode and clear screen
terminal::disable_raw_mode()?;
execute!(
io::stdout(),
terminal::Clear(ClearType::All),
cursor::MoveTo(0, 0)
)?;
println!("Simple image viewer closed.");
Ok(())
}
/// Render the image to the terminal
///
/// This function clears the screen, loads the image, resizes it to fit the
/// terminal dimensions, and renders it using the default settings
/// (Floyd-Steinberg dithering, Monochrome mode, auto Otsu threshold).
fn render_image(path: &Path) -> Result<(), Box<dyn std::error::Error>> {
// Clear screen before rendering
execute!(
io::stdout(),
terminal::Clear(ClearType::All),
cursor::MoveTo(0, 0)
)?;
// Load and render image with defaults (auto-resizes to terminal)
let grid = render_image_simple(path)?;
// Display in terminal
let mut renderer = TerminalRenderer::new()?;
renderer.render(&grid)?;
// Display help text at bottom
println!("\nPress Q or Esc to quit. Resize window to see automatic re-render.");
// Flush output to ensure everything is displayed
io::stdout().flush()?;
Ok(())
}