2024-01-15 08:00:56 +13:00
|
|
|
use std::path::Path;
|
|
|
|
use std::time::{Duration, Instant};
|
|
|
|
|
2023-12-04 00:06:42 +13:00
|
|
|
use image::DynamicImage;
|
|
|
|
use log::{debug, error};
|
|
|
|
use slint::ComponentHandle;
|
2024-01-15 08:00:56 +13:00
|
|
|
|
|
|
|
use czkawka_core::common::{get_dynamic_image_from_raw_image, IMAGE_RS_EXTENSIONS, RAW_IMAGE_EXTENSIONS};
|
|
|
|
|
2024-02-04 08:18:24 +13:00
|
|
|
use crate::{Callabler, CurrentTab, GuiState, MainWindow, Settings};
|
2023-12-04 00:06:42 +13:00
|
|
|
|
|
|
|
pub type ImageBufferRgba = image::ImageBuffer<image::Rgba<u8>, Vec<u8>>;
|
|
|
|
|
|
|
|
pub fn connect_show_preview(app: &MainWindow) {
|
|
|
|
let a = app.as_weak();
|
|
|
|
app.global::<Callabler>().on_load_image_preview(move |image_path| {
|
|
|
|
let app = a.upgrade().unwrap();
|
|
|
|
|
2024-02-04 08:18:24 +13:00
|
|
|
let settings = app.global::<Settings>();
|
|
|
|
let gui_state = app.global::<GuiState>();
|
|
|
|
|
|
|
|
let active_tab = gui_state.get_active_tab();
|
|
|
|
|
|
|
|
if active_tab == CurrentTab::SimilarImages && !settings.get_similar_images_show_image_preview() {
|
2024-02-11 08:36:14 +13:00
|
|
|
set_preview_visible(&gui_state, None);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do not load the same image again
|
|
|
|
if image_path == gui_state.get_preview_image_path() {
|
2024-02-04 08:18:24 +13:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-12-04 00:06:42 +13:00
|
|
|
let path = Path::new(image_path.as_str());
|
|
|
|
|
|
|
|
let res = load_image(path);
|
|
|
|
if let Some((load_time, img)) = res {
|
|
|
|
let start_timer_convert_time = Instant::now();
|
|
|
|
let slint_image = convert_into_slint_image(img);
|
|
|
|
let convert_time = start_timer_convert_time.elapsed();
|
|
|
|
|
|
|
|
let start_set_time = Instant::now();
|
2024-02-04 08:18:24 +13:00
|
|
|
gui_state.set_preview_image(slint_image);
|
2023-12-04 00:06:42 +13:00
|
|
|
let set_time = start_set_time.elapsed();
|
|
|
|
|
|
|
|
debug!(
|
|
|
|
"Loading image took: {:?}, converting image took: {:?}, setting image took: {:?}",
|
|
|
|
load_time, convert_time, set_time
|
|
|
|
);
|
2024-02-11 08:36:14 +13:00
|
|
|
set_preview_visible(&gui_state, Some(image_path.as_str()));
|
2023-12-04 00:06:42 +13:00
|
|
|
} else {
|
2024-02-11 08:36:14 +13:00
|
|
|
set_preview_visible(&gui_state, None);
|
2023-12-04 00:06:42 +13:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-02-11 08:36:14 +13:00
|
|
|
fn set_preview_visible(gui_state: &GuiState, preview: Option<&str>) {
|
|
|
|
if let Some(preview) = preview {
|
|
|
|
gui_state.set_preview_image_path(preview.into());
|
|
|
|
gui_state.set_preview_visible(true);
|
|
|
|
} else {
|
|
|
|
gui_state.set_preview_image_path("".into());
|
|
|
|
gui_state.set_preview_visible(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-04 00:06:42 +13:00
|
|
|
fn convert_into_slint_image(img: DynamicImage) -> slint::Image {
|
|
|
|
let image_buffer: ImageBufferRgba = img.to_rgba8();
|
|
|
|
let buffer = slint::SharedPixelBuffer::<slint::Rgba8Pixel>::clone_from_slice(image_buffer.as_raw(), image_buffer.width(), image_buffer.height());
|
|
|
|
slint::Image::from_rgba8(buffer)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn load_image(image_path: &Path) -> Option<(Duration, image::DynamicImage)> {
|
|
|
|
if !image_path.is_file() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
let image_name = image_path.to_string_lossy().to_string();
|
|
|
|
let image_extension = image_path.extension()?.to_string_lossy().to_lowercase();
|
|
|
|
|
2023-12-17 11:21:09 +13:00
|
|
|
let is_raw_image = RAW_IMAGE_EXTENSIONS.contains(&image_extension.as_str());
|
|
|
|
let is_normal_image = IMAGE_RS_EXTENSIONS.contains(&image_extension.as_str());
|
2023-12-04 00:06:42 +13:00
|
|
|
|
|
|
|
if !is_raw_image && !is_normal_image {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
let load_img_start_timer = Instant::now();
|
|
|
|
|
|
|
|
// TODO this needs to be run inside closure
|
|
|
|
let img = if is_normal_image {
|
|
|
|
match image::open(image_name) {
|
|
|
|
Ok(img) => img,
|
|
|
|
Err(e) => {
|
|
|
|
error!("Error while loading image: {}", e);
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if is_raw_image {
|
|
|
|
if let Some(img) = get_dynamic_image_from_raw_image(image_name) {
|
|
|
|
img
|
|
|
|
} else {
|
|
|
|
error!("Error while loading raw image - not sure why - try to guess");
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
panic!("Used not supported image extension");
|
|
|
|
};
|
|
|
|
|
|
|
|
Some((load_img_start_timer.elapsed(), img))
|
|
|
|
}
|