Newer
Older
use crate::component::grid::Grid;
use crate::component::image::{Image, ImagePosition};
use crate::egui::{TextureHandle, Ui, Vec2};
use crate::img;
use eframe::egui::{ColorImage, Frame, Pos2, Shape};
use eframe::emath::Rot2;
use rand::{thread_rng, Rng};
image: ColorImage,
texture: Option<TextureHandle>,
shapes: Vec<Shape>,
}
impl Default for Mosaic {
fn default() -> Self {
Self {
image: img!("squirrel0.png"),
texture: None,
shapes: Vec::new(),
}
}
ui.heading("Generative Image Processing");
Image::default()
.height(512.0)
.position(ImagePosition::FromCenter(Vec2::new(-300.0, 0.0)))
.margin(16.0)
.show(
ui,
self.texture.get_or_insert_with(|| {
ui.ctx().load_texture("squirrel0.png", self.image.clone())
}),
);
Grid {
size_pixels: 512.0,
alpha: 1.0,
offset_x: 300.0,
..Grid::default()
}
.show_with_overlays(ui.ctx(), |ui, to_screen| {
ui.ctx().request_repaint();
let mut rng = thread_rng();
for _ in 0..50 {
let x: f32 = rng.gen();
let y: f32 = rng.gen();
let size: f32 = rng.gen::<f32>() * 0.025;
let rot = Rot2::from_angle(rng.gen::<f32>() * std::f32::consts::TAU);
let center = Pos2::new(x, y);
let image_x =
((x * self.image.width() as f32) as usize).min(self.image.width() - 1);
let image_y =
((y * self.image.height() as f32) as usize).min(self.image.height() - 1);
self.shapes.push(
Triangle {
points: [
to_screen * (center + rot * Vec2::new(-1.0, -1.0) * size),
to_screen * (center + rot * Vec2::new(1.0, -1.0) * size),
to_screen * (center + rot * Vec2::new(-1.0, 1.0) * size),
],
stroke_width: 0.0,
fill: set_alpha(self.image[(image_x, image_y)], 0.2),
..Triangle::default()
}
.shape(),
);
}
ui.painter().extend(self.shapes.clone());
});