Decode images in parallel in gallery example
This commit is contained in:
parent
23039e758e
commit
c896cd8d31
2 changed files with 53 additions and 19 deletions
|
|
@ -130,6 +130,12 @@ impl fmt::Debug for Rgba {
|
|||
#[derive(Clone)]
|
||||
pub struct Bytes(bytes::Bytes);
|
||||
|
||||
impl Bytes {
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Bytes> for bytes::Bytes {
|
||||
fn from(value: Bytes) -> Self {
|
||||
value.0
|
||||
|
|
|
|||
|
|
@ -111,16 +111,21 @@ impl Gallery {
|
|||
let _ = self.visible.insert(id);
|
||||
|
||||
if self.downloaded.contains(&id) {
|
||||
let Some(Preview::Ready { thumbnail, .. }) =
|
||||
self.previews.get_mut(&id)
|
||||
let Some(Preview::Ready {
|
||||
thumbnail,
|
||||
blurhash,
|
||||
}) = self.previews.get_mut(&id)
|
||||
else {
|
||||
return Task::none();
|
||||
};
|
||||
|
||||
return image::allocate(image::Handle::from_bytes(
|
||||
thumbnail.bytes.clone(),
|
||||
))
|
||||
.map(Message::ThumbnailAllocated.with(id));
|
||||
if let Some(blurhash) = blurhash {
|
||||
blurhash.show(now);
|
||||
}
|
||||
|
||||
return to_rgba(thumbnail.bytes.clone())
|
||||
.then(image::allocate)
|
||||
.map(Message::ThumbnailAllocated.with(id));
|
||||
}
|
||||
|
||||
let _ = self.downloaded.insert(id);
|
||||
|
|
@ -165,7 +170,8 @@ impl Gallery {
|
|||
|
||||
let _ = self.previews.insert(id, preview);
|
||||
|
||||
image::allocate(image::Handle::from_bytes(bytes))
|
||||
to_rgba(bytes)
|
||||
.then(image::allocate)
|
||||
.map(Message::ThumbnailAllocated.with(id))
|
||||
}
|
||||
Message::ThumbnailAllocated(id, allocation) => {
|
||||
|
|
@ -173,19 +179,12 @@ impl Gallery {
|
|||
return Task::none();
|
||||
}
|
||||
|
||||
let Some(Preview::Ready {
|
||||
thumbnail,
|
||||
blurhash,
|
||||
..
|
||||
}) = self.previews.get_mut(&id)
|
||||
let Some(Preview::Ready { thumbnail, .. }) =
|
||||
self.previews.get_mut(&id)
|
||||
else {
|
||||
return Task::none();
|
||||
};
|
||||
|
||||
if let Some(blurhash) = blurhash {
|
||||
blurhash.show(now);
|
||||
}
|
||||
|
||||
thumbnail.show(allocation, now);
|
||||
|
||||
Task::none()
|
||||
|
|
@ -369,7 +368,7 @@ impl Blurhash {
|
|||
pub fn reset(&mut self) {
|
||||
self.fade_in = Animation::new(false)
|
||||
.easing(animation::Easing::EaseIn)
|
||||
.slow();
|
||||
.very_quick();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -427,9 +426,15 @@ impl Preview {
|
|||
fn is_animating(&self, now: Instant) -> bool {
|
||||
match &self {
|
||||
Self::Loading { blurhash } => blurhash.fade_in.is_animating(now),
|
||||
Self::Ready { thumbnail, .. } => {
|
||||
Self::Ready {
|
||||
thumbnail,
|
||||
blurhash,
|
||||
} => {
|
||||
thumbnail.fade_in.is_animating(now)
|
||||
|| thumbnail.zoom.is_animating(now)
|
||||
|| blurhash.as_ref().is_some_and(|blurhash| {
|
||||
blurhash.fade_in.is_animating(now)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -469,7 +474,7 @@ impl Thumbnail {
|
|||
self.allocation = None;
|
||||
self.fade_in = Animation::new(false)
|
||||
.easing(animation::Easing::EaseIn)
|
||||
.slow();
|
||||
.quick();
|
||||
}
|
||||
|
||||
pub fn show(&mut self, allocation: image::Allocation, now: Instant) {
|
||||
|
|
@ -547,3 +552,26 @@ impl Viewer {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn to_rgba(bytes: Bytes) -> Task<image::Handle> {
|
||||
use tokio::task;
|
||||
|
||||
Task::future(async move {
|
||||
task::spawn_blocking(move || {
|
||||
match ::image::load_from_memory(bytes.as_slice()) {
|
||||
Ok(image) => {
|
||||
let rgba = image.to_rgba8();
|
||||
|
||||
image::Handle::from_rgba(
|
||||
rgba.width(),
|
||||
rgba.height(),
|
||||
rgba.into_raw(),
|
||||
)
|
||||
}
|
||||
_ => image::Handle::from_bytes(bytes),
|
||||
}
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue