Build Image Filters with egui Sliders | Rust GUI Tutorial #14
Video: Build Image Filters with egui Sliders | Rust GUI Tutorial #14 by Taught by Celeste AI - AI Coding Coach
Watch full page →Build Image Filters with egui Sliders | Rust GUI Tutorial #14
Learn how to create an interactive image filter app in Rust using egui sliders to adjust brightness, contrast, saturation, and blur in real-time. This tutorial demonstrates binding slider values to filter parameters and rendering a live color preview to visualize changes instantly.
Code
use eframe::{egui, epi};
#[derive(Default)]
struct MyApp {
brightness: f32, // brightness adjustment: -100% to +100%
contrast: f32, // contrast adjustment: -100% to +100%
saturation: f32, // saturation adjustment: -100% to +100%
blur: f32, // blur radius in pixels: 0 to 10
}
impl MyApp {
// Calculate a preview color based on filter settings (simplified)
fn preview_color(&self) -> egui::Color32 {
// Start with a mid gray base color
let base = 128.0;
// Apply brightness: shift base color by brightness percentage
let bright = (base + base * self.brightness / 100.0).clamp(0.0, 255.0);
// Apply contrast: scale difference from 128 by contrast factor
let contrast_factor = (self.contrast / 100.0) + 1.0;
let contrasted = ((bright - 128.0) * contrast_factor + 128.0).clamp(0.0, 255.0);
// Apply saturation: here simplified as a grayscale intensity adjustment
let saturation_factor = (self.saturation / 100.0) + 1.0;
let saturated = (contrasted * saturation_factor).clamp(0.0, 255.0);
egui::Color32::from_gray(saturated as u8)
}
}
impl epi::App for MyApp {
fn name(&self) -> &str {
"Image Filters with egui Sliders"
}
fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Adjust Image Filters");
// Brightness slider with "%" suffix
ui.add(
egui::Slider::new(&mut self.brightness, -100.0..=100.0)
.text("Brightness")
.suffix("%"),
);
// Contrast slider with "%" suffix
ui.add(
egui::Slider::new(&mut self.contrast, -100.0..=100.0)
.text("Contrast")
.suffix("%"),
);
// Saturation slider with "%" suffix
ui.add(
egui::Slider::new(&mut self.saturation, -100.0..=100.0)
.text("Saturation")
.suffix("%"),
);
// Blur slider with "px" suffix
ui.add(
egui::Slider::new(&mut self.blur, 0.0..=10.0)
.text("Blur")
.suffix("px"),
);
// Reset button to default values
if ui.button("Reset All").clicked() {
*self = MyApp::default();
}
ui.separator();
// Draw preview rectangle showing the current filter color
let preview_color = self.preview_color();
let (rect, _response) = ui.allocate_exact_size(egui::vec2(100.0, 100.0), egui::Sense::hover());
ui.painter().rect_filled(rect, 0.0, preview_color);
ui.label(format!(
"Preview Color - Brightness: {:.0}%, Contrast: {:.0}%, Saturation: {:.0}%, Blur: {:.1}px",
self.brightness, self.contrast, self.saturation, self.blur
));
});
}
}
fn main() {
let app = MyApp::default();
let native_options = eframe::NativeOptions::default();
eframe::run_native(Box::new(app), native_options);
}
Key Points
- Use
egui::Slider::newto bind mutablef32values to sliders with defined ranges. - Add units like "%" or "px" to sliders using the
.suffix()method for clarity. - Implement simple image filter math for brightness, contrast, and saturation to update preview colors dynamically.
- Draw a live color preview rectangle using
allocate_exact_sizeandrect_filledfor immediate visual feedback. - Provide a "Reset All" button to restore default filter values by resetting the app state.