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)]
|
#[derive(Clone)]
|
||||||
pub struct Bytes(bytes::Bytes);
|
pub struct Bytes(bytes::Bytes);
|
||||||
|
|
||||||
|
impl Bytes {
|
||||||
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Bytes> for bytes::Bytes {
|
impl From<Bytes> for bytes::Bytes {
|
||||||
fn from(value: Bytes) -> Self {
|
fn from(value: Bytes) -> Self {
|
||||||
value.0
|
value.0
|
||||||
|
|
|
||||||
|
|
@ -111,16 +111,21 @@ impl Gallery {
|
||||||
let _ = self.visible.insert(id);
|
let _ = self.visible.insert(id);
|
||||||
|
|
||||||
if self.downloaded.contains(&id) {
|
if self.downloaded.contains(&id) {
|
||||||
let Some(Preview::Ready { thumbnail, .. }) =
|
let Some(Preview::Ready {
|
||||||
self.previews.get_mut(&id)
|
thumbnail,
|
||||||
|
blurhash,
|
||||||
|
}) = self.previews.get_mut(&id)
|
||||||
else {
|
else {
|
||||||
return Task::none();
|
return Task::none();
|
||||||
};
|
};
|
||||||
|
|
||||||
return image::allocate(image::Handle::from_bytes(
|
if let Some(blurhash) = blurhash {
|
||||||
thumbnail.bytes.clone(),
|
blurhash.show(now);
|
||||||
))
|
}
|
||||||
.map(Message::ThumbnailAllocated.with(id));
|
|
||||||
|
return to_rgba(thumbnail.bytes.clone())
|
||||||
|
.then(image::allocate)
|
||||||
|
.map(Message::ThumbnailAllocated.with(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = self.downloaded.insert(id);
|
let _ = self.downloaded.insert(id);
|
||||||
|
|
@ -165,7 +170,8 @@ impl Gallery {
|
||||||
|
|
||||||
let _ = self.previews.insert(id, preview);
|
let _ = self.previews.insert(id, preview);
|
||||||
|
|
||||||
image::allocate(image::Handle::from_bytes(bytes))
|
to_rgba(bytes)
|
||||||
|
.then(image::allocate)
|
||||||
.map(Message::ThumbnailAllocated.with(id))
|
.map(Message::ThumbnailAllocated.with(id))
|
||||||
}
|
}
|
||||||
Message::ThumbnailAllocated(id, allocation) => {
|
Message::ThumbnailAllocated(id, allocation) => {
|
||||||
|
|
@ -173,19 +179,12 @@ impl Gallery {
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(Preview::Ready {
|
let Some(Preview::Ready { thumbnail, .. }) =
|
||||||
thumbnail,
|
self.previews.get_mut(&id)
|
||||||
blurhash,
|
|
||||||
..
|
|
||||||
}) = self.previews.get_mut(&id)
|
|
||||||
else {
|
else {
|
||||||
return Task::none();
|
return Task::none();
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(blurhash) = blurhash {
|
|
||||||
blurhash.show(now);
|
|
||||||
}
|
|
||||||
|
|
||||||
thumbnail.show(allocation, now);
|
thumbnail.show(allocation, now);
|
||||||
|
|
||||||
Task::none()
|
Task::none()
|
||||||
|
|
@ -369,7 +368,7 @@ impl Blurhash {
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.fade_in = Animation::new(false)
|
self.fade_in = Animation::new(false)
|
||||||
.easing(animation::Easing::EaseIn)
|
.easing(animation::Easing::EaseIn)
|
||||||
.slow();
|
.very_quick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -427,9 +426,15 @@ impl Preview {
|
||||||
fn is_animating(&self, now: Instant) -> bool {
|
fn is_animating(&self, now: Instant) -> bool {
|
||||||
match &self {
|
match &self {
|
||||||
Self::Loading { blurhash } => blurhash.fade_in.is_animating(now),
|
Self::Loading { blurhash } => blurhash.fade_in.is_animating(now),
|
||||||
Self::Ready { thumbnail, .. } => {
|
Self::Ready {
|
||||||
|
thumbnail,
|
||||||
|
blurhash,
|
||||||
|
} => {
|
||||||
thumbnail.fade_in.is_animating(now)
|
thumbnail.fade_in.is_animating(now)
|
||||||
|| thumbnail.zoom.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.allocation = None;
|
||||||
self.fade_in = Animation::new(false)
|
self.fade_in = Animation::new(false)
|
||||||
.easing(animation::Easing::EaseIn)
|
.easing(animation::Easing::EaseIn)
|
||||||
.slow();
|
.quick();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show(&mut self, allocation: image::Allocation, now: Instant) {
|
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