fix: image flickering

This commit is contained in:
electria 2026-06-28 17:58:23 -07:00
commit 6e45b3afdc
Signed by: electria
SSH key fingerprint: SHA256:8LlB3ucPbBHqozqkhsNbaV5oG3SlzzqUj8FZDL6IPQs

View file

@ -9,16 +9,18 @@ use image::{EncodableLayout, ImageReader, RgbaImage, imageops};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
enum Message { enum Message {
ImageDisplayReady(Result<widget::image::Allocation, widget::image::Error>),
Event(iced::Event), Event(iced::Event),
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct State { struct State {
image: RgbaImage, image: RgbaImage,
image_handle: widget::image::Handle, image_display: Option<widget::image::Allocation>,
} }
impl State { impl State {
fn new() -> Self { fn new() -> (Self, Task<Message>) {
let image = if let Some(path) = env::args().nth(1) { let image = if let Some(path) = env::args().nth(1) {
ImageReader::open(path) ImageReader::open(path)
.unwrap() .unwrap()
@ -29,18 +31,34 @@ impl State {
RgbaImage::new(100, 100) RgbaImage::new(100, 100)
}; };
State { let allocate_image = widget::image::allocate(widget::image::Handle::from_rgba(
image_handle: widget::image::Handle::from_rgba(image.width(), image.height(), unsafe { image.width(),
std::mem::transmute::<_, &'static [u8]>(image.as_bytes()) image.height(),
}), unsafe { std::mem::transmute::<_, &'static [u8]>(image.as_bytes()) },
image, ))
} .map(Message::ImageDisplayReady);
(
State {
image_display: None,
image,
},
allocate_image,
)
} }
fn view(&self) -> Element<'_, Message, Theme, Renderer> { fn view(&self) -> Element<'_, Message, Theme, Renderer> {
widget::image(&self.image_handle).expand(true).into() if let Some(allocation) = self.image_display.as_ref() {
widget::image(allocation.handle()).expand(true).into()
} else {
widget::space().into()
}
} }
fn update(&mut self, message: Message) -> Task<Message> { fn update(&mut self, message: Message) -> Task<Message> {
match message { match message {
Message::ImageDisplayReady(result) => {
self.image_display = Some(result.unwrap());
}
Message::Event(iced::Event::Keyboard(keyboard::Event::KeyPressed { Message::Event(iced::Event::Keyboard(keyboard::Event::KeyPressed {
key, key,
modifiers, modifiers,
@ -59,11 +77,12 @@ impl State {
Key::Character("r") => { Key::Character("r") => {
self.image = imageops::rotate90(&self.image); self.image = imageops::rotate90(&self.image);
self.image_handle = widget::image::Handle::from_rgba( return widget::image::allocate(widget::image::Handle::from_rgba(
self.image.width(), self.image.width(),
self.image.height(), self.image.height(),
unsafe { std::mem::transmute::<_, &'static [u8]>(self.image.as_bytes()) }, unsafe { std::mem::transmute::<_, &'static [u8]>(self.image.as_bytes()) },
) ))
.map(Message::ImageDisplayReady);
} }
// ignore unused keys // ignore unused keys