summaryrefslogtreecommitdiffstats
path: root/src/image/image_view.rs
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2020-09-30 18:10:48 +0200
committerCanop <cano.petrole@gmail.com>2020-09-30 18:10:48 +0200
commitc5dc8563a39247b7d97402757eb07dc8054d99cb (patch)
treebe533503603a9a9356ff84319a8891ef73b22845 /src/image/image_view.rs
parent6e156533cd3663d83cd9ccd511e5301ed731c39a (diff)
image preview: cache resized image to avoid useless resizes
Diffstat (limited to 'src/image/image_view.rs')
-rw-r--r--src/image/image_view.rs58
1 files changed, 41 insertions, 17 deletions
diff --git a/src/image/image_view.rs b/src/image/image_view.rs
index ce45d7c..c09e036 100644
--- a/src/image/image_view.rs
+++ b/src/image/image_view.rs
@@ -24,24 +24,34 @@ use {
termimad::{Area},
};
+
+/// an already resized image, with the dimensions it
+/// was computed for (which may be different from the
+/// dimensions we got)
+struct CachedImage {
+ img: DynamicImage,
+ target_width: u32,
+ target_height: u32,
+}
+
/// an imageview can display an image in the terminal with
-/// a ration of one pixel per char in width.
+/// a ratio of one pixel per char in width.
pub struct ImageView {
- img: DynamicImage,
+ source_img: DynamicImage,
+ display_img: Option<CachedImage>,
}
impl ImageView {
pub fn new(path: &Path) -> Result<Self, ProgramError> {
- let img = time!(
+ let source_img = time!(
Debug,
"decode image",
path,
Reader::open(&path)?.decode()?
);
- let (width, height) = img.dimensions();
- debug!("image dimensions: {},{}", width, height);
Ok(Self {
- img,
+ source_img,
+ display_img: None,
})
}
pub fn display(
@@ -52,15 +62,30 @@ impl ImageView {
area: &Area,
con: &AppContext,
) -> Result<(), ProgramError> {
- let img = time!(
- Debug,
- "resize image",
- self.img.resize(
- area.width as u32,
- (area.height*2) as u32,
- FilterType::Triangle,
- ),
- );
+ let target_width = area.width as u32;
+ let target_height = (area.height*2) as u32;
+ let cached = self.display_img.as_ref()
+ .filter(|ci| ci.target_width==target_width && ci.target_height==target_height);
+ let img = match cached {
+ Some(ci) => &ci.img,
+ None => {
+ let img = time!(
+ Debug,
+ "resize image",
+ self.source_img.resize(
+ area.width as u32,
+ (area.height*2) as u32,
+ FilterType::Triangle,
+ ),
+ );
+ self.display_img = Some(CachedImage {
+ target_width,
+ target_height,
+ img,
+ });
+ &self.display_img.as_ref().unwrap().img
+ }
+ };
let (width, height) = img.dimensions();
debug!("resized image dimensions: {},{}", width, height);
debug_assert!(width <= area.width as u32);
@@ -100,7 +125,7 @@ impl ImageView {
panel_skin: &PanelSkin,
area: &Area,
) -> Result<(), ProgramError> {
- let dim = self.img.dimensions();
+ let dim = self.source_img.dimensions();
let s = format!("{} x {}", dim.0, dim.1);
if s.len() > area.width as usize {
return Ok(());
@@ -114,4 +139,3 @@ impl ImageView {
}
}
-