mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-07 20:15:23 +00:00
feature: add new image format + small fixes on the rendering of the images
This commit is contained in:
parent
6e6ce28bf5
commit
2a02c7801e
@ -255,39 +255,58 @@ pub fn try_preview(
|
||||
entry.name.clone(),
|
||||
&meta::loading(&format!("Loading {}", entry.name)),
|
||||
);
|
||||
|
||||
debug!("File {:?} is an image", entry.name);
|
||||
match ImageReader::open(path).unwrap().decode() {
|
||||
Ok(image) => {
|
||||
let preview_window_dimension = preview_window.map(|rect| {
|
||||
(u32::from(rect.width), u32::from(rect.height))
|
||||
});
|
||||
let image_preview_widget =
|
||||
ImagePreviewWidget::from_dynamic_image(
|
||||
image,
|
||||
preview_window_dimension,
|
||||
let option_image = match ImageReader::open(path) {
|
||||
Ok(reader) => match reader.with_guessed_format() {
|
||||
Ok(reader) => match reader.decode() {
|
||||
Ok(image) => Some(image),
|
||||
Err(e) => {
|
||||
warn!(
|
||||
"Error impossible to decode {}: {:?}",
|
||||
entry.name, e
|
||||
);
|
||||
None
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
warn!(
|
||||
"Error impossible to guess the format of {}: {:?}",
|
||||
entry.name, e
|
||||
);
|
||||
let total_lines = image_preview_widget
|
||||
.height()
|
||||
.try_into()
|
||||
.unwrap_or(u16::MAX);
|
||||
let content = PreviewContent::Image(image_preview_widget);
|
||||
let preview = Arc::new(Preview::new(
|
||||
entry.name.clone(),
|
||||
content,
|
||||
entry.icon,
|
||||
None,
|
||||
total_lines,
|
||||
));
|
||||
cache.lock().insert(entry.name.clone(), &preview);
|
||||
}
|
||||
None
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("Error opening file: {:?}", e);
|
||||
let p = meta::not_supported(&entry.name);
|
||||
cache.lock().insert(entry.name.clone(), &p);
|
||||
warn!("Error opening image {}: {:?}", entry.name, e);
|
||||
None
|
||||
}
|
||||
};
|
||||
if let Some(image) = option_image {
|
||||
let preview_window_dimension = preview_window.map(|rect| {
|
||||
(u32::from(rect.width - 2), u32::from(rect.height - 2)) // - 2 for the marge
|
||||
});
|
||||
let image_preview_widget = ImagePreviewWidget::from_dynamic_image(
|
||||
image,
|
||||
preview_window_dimension,
|
||||
);
|
||||
let total_lines =
|
||||
image_preview_widget.height().try_into().unwrap_or(u16::MAX);
|
||||
let content = PreviewContent::Image(image_preview_widget);
|
||||
let preview = Arc::new(Preview::new(
|
||||
entry.name.clone(),
|
||||
content,
|
||||
entry.icon,
|
||||
None,
|
||||
total_lines,
|
||||
));
|
||||
cache.lock().insert(entry.name.clone(), &preview);
|
||||
} else {
|
||||
let p = meta::not_supported(&entry.name);
|
||||
cache.lock().insert(entry.name.clone(), &p);
|
||||
}
|
||||
} else {
|
||||
debug!("File isn't text-based: {:?}", entry.name);
|
||||
debug!("File format isn't supported for preview: {:?}", entry.name);
|
||||
let preview = meta::not_supported(&entry.name);
|
||||
cache.lock().insert(entry.name.clone(), &preview);
|
||||
}
|
||||
|
@ -118,12 +118,12 @@ where
|
||||
fn from(path: P) -> Self {
|
||||
debug!("Getting file type for {:?}", path);
|
||||
let p = path.as_ref();
|
||||
if is_known_text_extension(p) {
|
||||
return FileType::Text;
|
||||
}
|
||||
if is_accepted_image_extension(p) {
|
||||
return FileType::Image;
|
||||
}
|
||||
if is_known_text_extension(p) {
|
||||
return FileType::Text;
|
||||
}
|
||||
if let Ok(mut f) = File::open(p) {
|
||||
let mut buffer = [0u8; 256];
|
||||
if let Ok(bytes_read) = f.read(&mut buffer) {
|
||||
@ -506,16 +506,10 @@ pub static KNOWN_IMAGE_FILE_EXTENSIONS: OnceLock<FxHashSet<&'static str>> =
|
||||
pub fn get_known_image_file_extensions() -> &'static FxHashSet<&'static str> {
|
||||
KNOWN_IMAGE_FILE_EXTENSIONS.get_or_init(|| {
|
||||
[
|
||||
//"avif",
|
||||
//"bmp",
|
||||
//"dds",
|
||||
//"farbfeld",
|
||||
"gif", //"hdr",
|
||||
"ico", "jpeg", "jpg", //"exr",
|
||||
"png", //"pnm",
|
||||
//"qoi",
|
||||
//"tga",
|
||||
"tif", "tiff", "webp",
|
||||
// "avif", requires the avif-native feature, uses the libdav1d C library.
|
||||
// dds, dosen't work for some reason
|
||||
"bmp", "ff", "gif", "hdr", "ico", "jpeg", "jpg", "exr", "png",
|
||||
"pnm", "qoi", "tga", "tif", "webp",
|
||||
]
|
||||
.iter()
|
||||
.copied()
|
||||
|
@ -8,7 +8,7 @@ use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
static PIXEL_STRING: &str = "▀";
|
||||
const FILTER_TYPE: FilterType = FilterType::Triangle;
|
||||
const FILTER_TYPE: FilterType = FilterType::Lanczos3;
|
||||
|
||||
// use to reduce the size of the image before storing it
|
||||
const DEFAULT_CACHED_WIDTH: u32 = 50;
|
||||
@ -28,7 +28,7 @@ impl Widget for &ImagePreviewWidget {
|
||||
let width = self.width();
|
||||
// offset of the left top corner where the image is centered
|
||||
let total_width = usize::from(area.width) + 2 * usize::from(area.x);
|
||||
let x_offset = total_width.saturating_sub(width) / 2;
|
||||
let x_offset = total_width.saturating_sub(width) / 2 + 1;
|
||||
let total_height = usize::from(area.height) + 2 * usize::from(area.y);
|
||||
let y_offset = total_height.saturating_sub(height) / 2;
|
||||
|
||||
@ -42,7 +42,8 @@ impl Widget for &ImagePreviewWidget {
|
||||
for (x, cell) in row.iter().enumerate() {
|
||||
let pos_x =
|
||||
u16::try_from(x_offset + x).unwrap_or(u16::MAX);
|
||||
if pos_x >= area_border_left && pos_x < area_border_right {
|
||||
if pos_x >= area_border_left && pos_x <= area_border_right
|
||||
{
|
||||
if let Some(buf_cell) =
|
||||
buf.cell_mut(Position::new(pos_x, pos_y))
|
||||
{
|
||||
@ -74,29 +75,28 @@ impl ImagePreviewWidget {
|
||||
dynamic_image: DynamicImage,
|
||||
dimension: Option<(u32, u32)>,
|
||||
) -> Self {
|
||||
// first quick resize
|
||||
let (window_width, window_height) =
|
||||
dimension.unwrap_or((DEFAULT_CACHED_WIDTH, DEFAULT_CACHED_HEIGHT));
|
||||
let big_resized_image = if dynamic_image.width() > window_width * 4
|
||||
|| dynamic_image.height() > window_height * 4
|
||||
let (max_width, max_height) = (window_width, window_height * 2 - 2); // -2 to have some space with the title
|
||||
|
||||
// first quick resize
|
||||
let big_resized_image = if dynamic_image.width() > max_width * 4
|
||||
|| dynamic_image.height() > max_height * 4
|
||||
{
|
||||
dynamic_image.resize(
|
||||
window_width * 4,
|
||||
window_height * 4,
|
||||
max_width * 4,
|
||||
max_height * 4,
|
||||
FilterType::Nearest,
|
||||
)
|
||||
} else {
|
||||
dynamic_image
|
||||
};
|
||||
|
||||
// this time resize with the filter
|
||||
let resized_image = if big_resized_image.width() > window_width
|
||||
|| big_resized_image.height() > window_height
|
||||
let resized_image = if big_resized_image.width() > max_width
|
||||
|| big_resized_image.height() > max_height
|
||||
{
|
||||
big_resized_image.resize(
|
||||
window_width,
|
||||
DEFAULT_CACHED_HEIGHT,
|
||||
FILTER_TYPE,
|
||||
)
|
||||
big_resized_image.resize(max_width, max_height, FILTER_TYPE)
|
||||
} else {
|
||||
big_resized_image
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user