summaryrefslogtreecommitdiffstats
path: root/src/image/image_view.rs
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2020-08-04 11:19:50 +0200
committerCanop <cano.petrole@gmail.com>2020-08-04 11:19:50 +0200
commitb5ef92d0f52c983e7f25a82a8cdbed12b714baa0 (patch)
tree33b7a5d735870255b0728f95d1dc89641b1c0084 /src/image/image_view.rs
parent522ecdb78e17c1e98fef55419794282b781ef88a (diff)
display image dimensions in image preview
Diffstat (limited to 'src/image/image_view.rs')
-rw-r--r--src/image/image_view.rs111
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(())
+ }
}