use image::DynamicImage;
use ratatui::layout::{Rect, Size};
use ratatui::Frame;
use ratatui_image::picker::Picker;
use ratatui_image::protocol::Protocol;
use ratatui_image::{Image, Resize};
pub struct Cover {
img: DynamicImage,
picker: Picker,
cached: Option<(Rect, Protocol)>,
}
impl Cover {
pub fn make_picker() -> Picker {
Picker::from_query_stdio().unwrap_or_else(|_| Picker::halfblocks())
}
pub fn load(path: &str, picker: Picker) -> Option<Self> {
let img = image::open(path).ok()?;
Some(Self::from_image(img, picker))
}
pub fn from_image(img: DynamicImage, picker: Picker) -> Self {
Self {
img,
picker,
cached: None,
}
}
pub fn render(&mut self, frame: &mut Frame, area: Rect) {
if area.width == 0 || area.height == 0 {
return;
}
let needs_encode = self
.cached
.as_ref()
.map(|(cached_area, _)| *cached_area != area)
.unwrap_or(true);
if needs_encode {
match self
.picker
.new_protocol(self.img.clone(), Size::new(area.width, area.height), Resize::Fit(None))
{
Ok(protocol) => self.cached = Some((area, protocol)),
Err(_) => return,
}
}
if let Some((_, protocol)) = &self.cached {
frame.render_widget(Image::new(protocol), area);
}
}
}