diff options
author | Canop <cano.petrole@gmail.com> | 2020-08-04 11:19:50 +0200 |
---|---|---|
committer | Canop <cano.petrole@gmail.com> | 2020-08-04 11:19:50 +0200 |
commit | b5ef92d0f52c983e7f25a82a8cdbed12b714baa0 (patch) | |
tree | 33b7a5d735870255b0728f95d1dc89641b1c0084 /src/image/image_view.rs | |
parent | 522ecdb78e17c1e98fef55419794282b781ef88a (diff) |
display image dimensions in image preview
Diffstat (limited to 'src/image/image_view.rs')
-rw-r--r-- | src/image/image_view.rs | 111 |
1 files changed, 36 insertions, 75 deletions
diff --git a/src/image/image_view.rs b/src/image/image_view.rs index 7a4fbb3..5e93dc5 100644 --- a/src/image/image_view.rs +++ b/src/image/image_view.rs @@ -1,4 +1,5 @@ use { + super::double_line::DoubleLine, crate::{ display::{fill_bg, Screen, W}, errors::ProgramError, @@ -7,12 +8,8 @@ use { crossterm::{ cursor, style::{ - Attributes, Color, - ContentStyle, - PrintStyledContent, SetBackgroundColor, - StyledContent, }, QueueableCommand, }, @@ -21,7 +18,6 @@ use { DynamicImage, GenericImageView, imageops::FilterType, - Rgba, }, std::{ path::Path, @@ -29,75 +25,19 @@ use { termimad::{Area}, }; +/// an imageview can display an image in the terminal with +/// a ration of one pixel per char in width. pub struct ImageView { img: DynamicImage, } -const UPPER_HALF_BLOCK: char = '▀'; - -// Each char row covers two pixel lines. -struct DoubleLine { - img_width: usize, - pixels: Vec<Color>, // size twice img_width -} -impl DoubleLine { - fn new(img_width: usize) -> Self { - Self { - img_width, - pixels: Vec::with_capacity(2 * img_width), - } - } - fn push(&mut self, rgba: Rgba<u8>) { - self.pixels.push(Color::Rgb{ - r: rgba[0], - g: rgba[1], - b: rgba[2], - }); - } - fn is_empty(&self) -> bool { - self.pixels.is_empty() - } - fn is_full(&self) -> bool { - self.pixels.len() == 2 * self.img_width - } - fn write( - &mut self, - w: &mut W, - left_margin: usize, - right_margin: usize, - bg: Color, - ) -> Result<(), ProgramError> { - debug_assert!(self.pixels.len()==self.img_width || self.pixels.len() == 2*self.img_width); - // we may have either one or two lines - let simple = self.pixels.len() < 2 * self.img_width; - fill_bg(w, left_margin, bg)?; - for i in 0..self.img_width { - let foreground_color = Some(self.pixels[i]); - let background_color = if simple { - None - } else { - Some(self.pixels[i + self.img_width]) - }; - w.queue(PrintStyledContent(StyledContent::new( - ContentStyle { - foreground_color, - background_color, - attributes: Attributes::default(), - }, - UPPER_HALF_BLOCK, - )))?; - } - fill_bg(w, right_margin, bg)?; - self.pixels.clear(); - Ok(()) - } -} - -// TODO disable if not true color ? impl ImageView { pub fn new(path: &Path) -> Result<Self, ProgramError> { - let img = Reader::open(&path)? - .decode()?; + let img = time!( + Debug, + "decode image", + Reader::open(&path)?.decode()? + ); let (width, height) = img.dimensions(); debug!("image dimensions: {},{}", width, height); Ok(Self { @@ -111,12 +51,15 @@ impl ImageView { panel_skin: &PanelSkin, area: &Area, ) -> Result<(), ProgramError> { - debug!("img view area: {:?}", area); - let img = self.img.resize( - area.width as u32, - (area.height*2) as u32, - FilterType::Triangle, - //FilterType::Nearest, + let img = time!( + Debug, + "resize image", + self.img.resize( + area.width as u32, + (area.height*2) as u32, + FilterType::Triangle, + //FilterType::Nearest, + ), ); let (width, height) = img.dimensions(); debug!("resized image dimensions: {},{}", width, height); @@ -125,7 +68,6 @@ impl ImageView { let bg = styles.preview.get_bg() .or_else(|| styles.default.get_bg()) .unwrap_or(Color::AnsiValue(238)); - //let mut (x, y) = (0, 0); let mut double_line = DoubleLine::new(width as usize); let mut y = area.top; let margin = area.width as usize - width as usize; @@ -151,6 +93,25 @@ impl ImageView { } Ok(()) } + pub fn display_info( + &mut self, + w: &mut W, + _screen: &Screen, + panel_skin: &PanelSkin, + area: &Area, + ) -> Result<(), ProgramError> { + let dim = self.img.dimensions(); + let s = format!("{} x {}", dim.0, dim.1); + if s.len() > area.width as usize { + return Ok(()); + } + w.queue(cursor::MoveTo( + area.left + area.width - s.len() as u16, + area.top, + ))?; + panel_skin.styles.default.queue(w, s)?; + Ok(()) + } } |