fn main() {
use fovea::Size;
use fovea::image::{Image, ImageView, SubView};
use fovea::pixel::Mono8;
let pixels: Vec<Mono8> = (0u32..96).map(|i| Mono8::new((i % 256) as u8)).collect();
let img = Image::from_vec(12, 8, pixels).unwrap();
println!("Source image: {}×{}", img.width(), img.height());
let tile_size = Size::new(4, 4);
let tiles: Vec<_> = img.tiles(tile_size).collect();
println!(
"\nTile grid: {} tiles (target {}×{})",
tiles.len(),
tile_size.width,
tile_size.height
);
assert_eq!(tiles.len(), 6, "12/4 * 8/4 = 3*2 = 6 tiles");
println!("\nPer-tile average intensity:");
for (i, tile) in tiles.iter().enumerate() {
let avg = average_intensity(*tile);
println!(
" Tile {i}: {}×{} — avg intensity = {avg:.1}",
tile.width(),
tile.height()
);
}
let (brightest_idx, brightest_avg) = tiles
.iter()
.enumerate()
.map(|(i, tile)| (i, average_intensity(*tile)))
.max_by(|a, b| a.1.partial_cmp(&b.1).unwrap())
.unwrap();
println!("\nBrightest tile: #{brightest_idx} (avg = {brightest_avg:.1})");
let big_tile = Size::new(5, 5);
let partial_tiles: Vec<_> = img.tiles(big_tile).collect();
println!(
"\nPartial-edge tiles ({}×{}):",
big_tile.width, big_tile.height
);
for (i, tile) in partial_tiles.iter().enumerate() {
println!(" Tile {i}: {}×{}", tile.width(), tile.height());
}
assert_eq!(partial_tiles.len(), 6);
let last = partial_tiles.last().unwrap();
assert_eq!(last.width(), 2, "rightmost column: 12 - 5 - 5 = 2");
assert_eq!(last.height(), 3, "bottom row: 8 - 5 = 3");
let roi_rect = fovea::Rectangle::new((2, 1), (4, 3));
let roi = img.roi(roi_rect).expect("ROI is within bounds");
println!("\nROI at (2,1) size 4×3:");
for y in 0..roi.height() {
for x in 0..roi.width() {
let v = roi.pixel_at(x, y).value();
print!("{v:3} ");
}
println!();
}
assert_eq!(
roi.pixel_at(0, 0).value(),
img.pixel_at(2, 1).value(),
"ROI origin maps to parent (2,1)"
);
println!("\nDone! Tile-based processing enables efficient, parallel-friendly pipelines.");
}
fn average_intensity(view: impl fovea::image::ImageView<Pixel = fovea::pixel::Mono8>) -> f64 {
let mut sum = 0u64;
for y in 0..view.height() {
for x in 0..view.width() {
sum += view.pixel_at(x, y).value() as u64;
}
}
let count = view.width() * view.height();
if count == 0 {
return 0.0;
}
sum as f64 / count as f64
}