diff options
author | Canop <cano.petrole@gmail.com> | 2020-09-30 18:10:48 +0200 |
---|---|---|
committer | Canop <cano.petrole@gmail.com> | 2020-09-30 18:10:48 +0200 |
commit | c5dc8563a39247b7d97402757eb07dc8054d99cb (patch) | |
tree | be533503603a9a9356ff84319a8891ef73b22845 /src/image/image_view.rs | |
parent | 6e156533cd3663d83cd9ccd511e5301ed731c39a (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.rs | 58 |
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 { } } - |