From f334bd6975911309fd4e86148fc93ad987149b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mikrut?= <41945903+qarmin@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:33:06 +0100 Subject: [PATCH] Add better custom selecting (#479) --- czkawka_cli/src/commands.rs | 5 +- czkawka_core/src/duplicate.rs | 2 - czkawka_core/src/similar_images.rs | 38 ++++++++------- czkawka_gui/src/compute_results.rs | 11 +++-- czkawka_gui/src/connect_button_search.rs | 11 +++-- czkawka_gui/src/connect_settings.rs | 2 +- .../src/connect_similar_image_size_change.rs | 37 +++++++++----- czkawka_gui/src/gui_main_notebook.rs | 23 +++++++-- czkawka_gui/ui/main_window.glade | 48 ++++++++++++------- 9 files changed, 115 insertions(+), 62 deletions(-) diff --git a/czkawka_cli/src/commands.rs b/czkawka_cli/src/commands.rs index 960ed80..8f7e659 100644 --- a/czkawka_cli/src/commands.rs +++ b/czkawka_cli/src/commands.rs @@ -382,10 +382,11 @@ fn parse_similar_hash_algorithm(src: &str) -> Result { fn parse_image_hash_size(src: &str) -> Result { let hash_size; hash_size = match src.to_lowercase().as_str() { - "4" => 4, "8" => 8, "16" => 16, - _ => return Err("Couldn't parse the image hash size (allowed: 4, 8, 16)".to_string()), + "32" => 32, + "64" => 64, + _ => return Err("Couldn't parse the image hash size (allowed: 8, 16, 32, 64)".to_string()), }; Ok(hash_size) } diff --git a/czkawka_core/src/duplicate.rs b/czkawka_core/src/duplicate.rs index 791393b..ceb0b06 100644 --- a/czkawka_core/src/duplicate.rs +++ b/czkawka_core/src/duplicate.rs @@ -811,8 +811,6 @@ impl DuplicateFinder { } if self.use_prehash_cache { - println!("non cached - {}", non_cached_files_to_check.values().map(|e| e.len()).sum::()); - println!("cached - {}", records_already_cached.values().map(|e| e.len()).sum::()); // All results = records already cached + computed results let mut save_cache_to_hashmap: BTreeMap = Default::default(); diff --git a/czkawka_core/src/similar_images.rs b/czkawka_core/src/similar_images.rs index 4cec75d..001421c 100644 --- a/czkawka_core/src/similar_images.rs +++ b/czkawka_core/src/similar_images.rs @@ -25,10 +25,11 @@ use crate::common_messages::Messages; use crate::common_traits::{DebugPrint, PrintResults, SaveResults}; // TODO check for better values -pub const SIMILAR_VALUES: [[u32; 6]; 3] = [ - [0, 1, 2, 3, 4, 5], // 4 - Max 16 - [0, 2, 5, 7, 14, 20], // 8 - Max 256 - [2, 5, 10, 20, 40, 80], // 16 - Max 65536 +pub const SIMILAR_VALUES: [[u32; 6]; 4] = [ + [0, 2, 5, 7, 14, 20], // 8 + [2, 5, 15, 30, 40, 40], // 16 + [4, 10, 20, 40, 40, 40], // 32 + [6, 20, 40, 40, 40, 40], // 64 ]; #[derive(Debug)] @@ -144,7 +145,7 @@ impl SimilarImages { pub fn set_hash_size(&mut self, hash_size: u8) { self.hash_size = match hash_size { - 4 | 8 | 16 => hash_size, + 8 | 16 | 32 | 64 => hash_size, e => { panic!("Invalid value of hash size {}", e); } @@ -539,9 +540,10 @@ impl SimilarImages { // TODO optimize this for big temp_max_similarity values // TODO maybe Simialar(u32) is enough instead SIMILAR_VALUES value? let temp_max_similarity = match self.hash_size { - 4 => SIMILAR_VALUES[0][5], - 8 => SIMILAR_VALUES[1][5], - 16 => SIMILAR_VALUES[2][5], + 8 => SIMILAR_VALUES[0][5], + 16 => SIMILAR_VALUES[1][4], + 32 => SIMILAR_VALUES[2][3], + 64 => SIMILAR_VALUES[3][2], _ => panic!(), }; @@ -759,9 +761,7 @@ pub fn save_hashes_to_file(hashmap: &BTreeMap, text_messages: let mut writer = BufWriter::new(file_handler); for file_entry in hashmap.values() { - let mut string: String = String::with_capacity(128); - - string += format!("{}//{}//{}//{}", file_entry.path.display(), file_entry.size, file_entry.dimensions, file_entry.modified_date).as_str(); + let mut string: String = format!("{}//{}//{}//{}", file_entry.path.display(), file_entry.size, file_entry.dimensions, file_entry.modified_date); for hash in &file_entry.hash { string.push_str("//"); @@ -873,9 +873,10 @@ fn get_cache_file(hash_size: &u8, hash_alg: &HashAlg, image_filter: &FilterType) pub fn get_string_from_similarity(similarity: &Similarity, hash_size: u8) -> String { let index_preset = match hash_size { - 4 => 0, - 8 => 1, - 16 => 2, + 8 => 0, + 16 => 1, + 32 => 2, + 64 => 3, _ => panic!(), }; @@ -926,9 +927,10 @@ pub fn get_string_from_similarity(similarity: &Similarity, hash_size: u8) -> Str pub fn return_similarity_from_similarity_preset(similarity_preset: &SimilarityPreset, hash_size: u8) -> Similarity { let index_preset = match hash_size { - 4 => 0, - 8 => 1, - 16 => 2, + 8 => 0, + 16 => 1, + 32 => 2, + 64 => 3, _ => panic!(), }; match similarity_preset { @@ -972,7 +974,7 @@ pub fn test_image_conversion_speed() { Ok(img_open) => { for alg in [HashAlg::Blockhash, HashAlg::Gradient, HashAlg::DoubleGradient, HashAlg::VertGradient, HashAlg::Mean] { for filter in [FilterType::Lanczos3, FilterType::CatmullRom, FilterType::Gaussian, FilterType::Nearest, FilterType::Triangle] { - for size in [2, 4, 8, 16, 32, 64] { + for size in [8, 16, 32, 64] { let hasher_config = HasherConfig::new().hash_alg(alg).resize_filter(filter).hash_size(size, size); let start = SystemTime::now(); diff --git a/czkawka_gui/src/compute_results.rs b/czkawka_gui/src/compute_results.rs index 87d718c..a9f1f4e 100644 --- a/czkawka_gui/src/compute_results.rs +++ b/czkawka_gui/src/compute_results.rs @@ -46,9 +46,10 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< let buttons_names = gui_data.bottom_buttons.buttons_names.clone(); let window_progress = gui_data.progress_window.window_progress.clone(); let taskbar_state = gui_data.taskbar_state.clone(); - let radio_button_similar_hash_size_4 = gui_data.main_notebook.radio_button_similar_hash_size_4.clone(); let radio_button_similar_hash_size_8 = gui_data.main_notebook.radio_button_similar_hash_size_8.clone(); let radio_button_similar_hash_size_16 = gui_data.main_notebook.radio_button_similar_hash_size_16.clone(); + let radio_button_similar_hash_size_32 = gui_data.main_notebook.radio_button_similar_hash_size_32.clone(); + let radio_button_similar_hash_size_64 = gui_data.main_notebook.radio_button_similar_hash_size_64.clone(); let main_context = glib::MainContext::default(); let _guard = main_context.acquire().unwrap(); @@ -64,12 +65,14 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< notebook_main.set_sensitive(true); let hash_size; - if radio_button_similar_hash_size_4.is_active() { - hash_size = 4; - } else if radio_button_similar_hash_size_8.is_active() { + if radio_button_similar_hash_size_8.is_active() { hash_size = 8; } else if radio_button_similar_hash_size_16.is_active() { hash_size = 16; + } else if radio_button_similar_hash_size_32.is_active() { + hash_size = 32; + } else if radio_button_similar_hash_size_64.is_active() { + hash_size = 64; } else { panic!("No radio button is pressed"); } diff --git a/czkawka_gui/src/connect_button_search.rs b/czkawka_gui/src/connect_button_search.rs index b16b367..eb12ee7 100644 --- a/czkawka_gui/src/connect_button_search.rs +++ b/czkawka_gui/src/connect_button_search.rs @@ -95,9 +95,10 @@ pub fn connect_button_search( let check_button_duplicates_use_prehash_cache = gui_data.settings.check_button_duplicates_use_prehash_cache.clone(); let entry_settings_cache_file_minimal_size = gui_data.settings.entry_settings_cache_file_minimal_size.clone(); let entry_settings_prehash_cache_file_minimal_size = gui_data.settings.entry_settings_prehash_cache_file_minimal_size.clone(); - let radio_button_similar_hash_size_4 = gui_data.main_notebook.radio_button_similar_hash_size_4.clone(); let radio_button_similar_hash_size_8 = gui_data.main_notebook.radio_button_similar_hash_size_8.clone(); let radio_button_similar_hash_size_16 = gui_data.main_notebook.radio_button_similar_hash_size_16.clone(); + let radio_button_similar_hash_size_32 = gui_data.main_notebook.radio_button_similar_hash_size_32.clone(); + let radio_button_similar_hash_size_64 = gui_data.main_notebook.radio_button_similar_hash_size_64.clone(); let radio_button_resize_algorithm_catmullrom = gui_data.main_notebook.radio_button_resize_algorithm_catmullrom.clone(); let radio_button_resize_algorithm_lanczos3 = gui_data.main_notebook.radio_button_resize_algorithm_lanczos3.clone(); let radio_button_resize_algorithm_nearest = gui_data.main_notebook.radio_button_resize_algorithm_nearest.clone(); @@ -292,12 +293,14 @@ pub fn connect_button_search( get_list_store(&tree_view_similar_images_finder).clear(); let hash_size; - if radio_button_similar_hash_size_4.is_active() { - hash_size = 4; - } else if radio_button_similar_hash_size_8.is_active() { + if radio_button_similar_hash_size_8.is_active() { hash_size = 8; } else if radio_button_similar_hash_size_16.is_active() { hash_size = 16; + } else if radio_button_similar_hash_size_32.is_active() { + hash_size = 32; + } else if radio_button_similar_hash_size_64.is_active() { + hash_size = 64; } else { panic!("No radio button is pressed"); } diff --git a/czkawka_gui/src/connect_settings.rs b/czkawka_gui/src/connect_settings.rs index 9eca16d..6ff75ef 100644 --- a/czkawka_gui/src/connect_settings.rs +++ b/czkawka_gui/src/connect_settings.rs @@ -143,7 +143,7 @@ pub fn connect_settings(gui_data: &GuiData) { dialog.connect_response(move |dialog, response_type| { if response_type == ResponseType::Ok { let mut messages: Messages = Messages::new(); - for hash_size in [8, 16, 32].iter() { + for hash_size in [8, 16, 32, 64].iter() { for image_filter in [FilterType::Lanczos3, FilterType::CatmullRom, FilterType::Gaussian, FilterType::Nearest, FilterType::Triangle].iter() { for hash_alg in [HashAlg::Blockhash, HashAlg::Gradient, HashAlg::DoubleGradient, HashAlg::VertGradient, HashAlg::Mean].iter() { if let Some(cache_entries) = czkawka_core::similar_images::load_hashes_from_file(&mut messages, true, *hash_size, *hash_alg, *image_filter) { diff --git a/czkawka_gui/src/connect_similar_image_size_change.rs b/czkawka_gui/src/connect_similar_image_size_change.rs index c6d7473..1304f05 100644 --- a/czkawka_gui/src/connect_similar_image_size_change.rs +++ b/czkawka_gui/src/connect_similar_image_size_change.rs @@ -5,29 +5,44 @@ use czkawka_core::similar_images::SIMILAR_VALUES; use crate::gui_data::GuiData; pub fn connect_similar_image_size_change(gui_data: &GuiData) { - // This should set values to max possible value like in return_similarity_from_similarity_preset and get_string_from_similarity - { - let radio_button_similar_hash_size_4 = gui_data.main_notebook.radio_button_similar_hash_size_4.clone(); - let scale_similarity_similar_images = gui_data.main_notebook.scale_similarity_similar_images.clone(); - radio_button_similar_hash_size_4.connect_toggled(move |_| { - scale_similarity_similar_images.set_range(0_f64, SIMILAR_VALUES[0][5] as f64); - scale_similarity_similar_images.set_fill_level(SIMILAR_VALUES[0][5] as f64); - }); - } { let radio_button_similar_hash_size_8 = gui_data.main_notebook.radio_button_similar_hash_size_8.clone(); + let label_similar_images_minimal_similarity = gui_data.main_notebook.label_similar_images_minimal_similarity.clone(); let scale_similarity_similar_images = gui_data.main_notebook.scale_similarity_similar_images.clone(); radio_button_similar_hash_size_8.connect_toggled(move |_| { - scale_similarity_similar_images.set_range(0_f64, SIMILAR_VALUES[1][5] as f64); - scale_similarity_similar_images.set_fill_level(SIMILAR_VALUES[1][5] as f64); + scale_similarity_similar_images.set_range(0_f64, SIMILAR_VALUES[0][5] as f64); + scale_similarity_similar_images.set_fill_level(SIMILAR_VALUES[0][5] as f64); + label_similar_images_minimal_similarity.set_text(" Minimal "); }); } { let radio_button_similar_hash_size_16 = gui_data.main_notebook.radio_button_similar_hash_size_16.clone(); + let label_similar_images_minimal_similarity = gui_data.main_notebook.label_similar_images_minimal_similarity.clone(); let scale_similarity_similar_images = gui_data.main_notebook.scale_similarity_similar_images.clone(); radio_button_similar_hash_size_16.connect_toggled(move |_| { + scale_similarity_similar_images.set_range(0_f64, SIMILAR_VALUES[1][5] as f64); + scale_similarity_similar_images.set_fill_level(SIMILAR_VALUES[1][5] as f64); + label_similar_images_minimal_similarity.set_text(" Very Small "); + }); + } + { + let radio_button_similar_hash_size_32 = gui_data.main_notebook.radio_button_similar_hash_size_32.clone(); + let label_similar_images_minimal_similarity = gui_data.main_notebook.label_similar_images_minimal_similarity.clone(); + let scale_similarity_similar_images = gui_data.main_notebook.scale_similarity_similar_images.clone(); + radio_button_similar_hash_size_32.connect_toggled(move |_| { scale_similarity_similar_images.set_range(0_f64, SIMILAR_VALUES[2][5] as f64); scale_similarity_similar_images.set_fill_level(SIMILAR_VALUES[2][5] as f64); + label_similar_images_minimal_similarity.set_text(" Small "); + }); + } + { + let radio_button_similar_hash_size_64 = gui_data.main_notebook.radio_button_similar_hash_size_64.clone(); + let label_similar_images_minimal_similarity = gui_data.main_notebook.label_similar_images_minimal_similarity.clone(); + let scale_similarity_similar_images = gui_data.main_notebook.scale_similarity_similar_images.clone(); + radio_button_similar_hash_size_64.connect_toggled(move |_| { + scale_similarity_similar_images.set_range(0_f64, SIMILAR_VALUES[3][5] as f64); + scale_similarity_similar_images.set_fill_level(SIMILAR_VALUES[3][5] as f64); + label_similar_images_minimal_similarity.set_text(" Medium "); }); } } diff --git a/czkawka_gui/src/gui_main_notebook.rs b/czkawka_gui/src/gui_main_notebook.rs index 4334c60..64e2fc1 100644 --- a/czkawka_gui/src/gui_main_notebook.rs +++ b/czkawka_gui/src/gui_main_notebook.rs @@ -83,9 +83,12 @@ pub struct GuiMainNotebook { pub radio_button_similar_hash_algorithm_vertgradient: gtk::RadioButton, pub radio_button_similar_hash_algorithm_doublegradient: gtk::RadioButton, - pub radio_button_similar_hash_size_4: gtk::RadioButton, pub radio_button_similar_hash_size_8: gtk::RadioButton, pub radio_button_similar_hash_size_16: gtk::RadioButton, + pub radio_button_similar_hash_size_32: gtk::RadioButton, + pub radio_button_similar_hash_size_64: gtk::RadioButton, + + pub label_similar_images_minimal_similarity: gtk::Label, pub image_preview_similar_images: gtk::Image, pub image_preview_duplicates: gtk::Image, @@ -187,6 +190,10 @@ impl GuiMainNotebook { let radio_button_hash_type_crc32: gtk::RadioButton = builder.object("radio_button_hash_type_crc32").unwrap(); let radio_button_hash_type_xxh3: gtk::RadioButton = builder.object("radio_button_hash_type_xxh3").unwrap(); + radio_button_hash_type_blake3.set_tooltip_text(Some("Blake3 is cryptographic hash function. It is used as default hash algorithm, because it is very fast.")); + radio_button_hash_type_crc32.set_tooltip_text(Some("CRC32 is simple hash function. It should be faster than Blake3, but probably may have very rarely some collisions.")); + radio_button_hash_type_xxh3.set_tooltip_text(Some("XXH3 is very similar in case of performance and hash quality to Blake3, so such modes can be easily used .")); + let radio_button_resize_algorithm_lanczos3: gtk::RadioButton = builder.object("radio_button_resize_algorithm_lanczos3").unwrap(); let radio_button_resize_algorithm_nearest: gtk::RadioButton = builder.object("radio_button_resize_algorithm_nearest").unwrap(); let radio_button_resize_algorithm_triangle: gtk::RadioButton = builder.object("radio_button_resize_algorithm_triangle").unwrap(); @@ -199,9 +206,17 @@ impl GuiMainNotebook { let radio_button_similar_hash_algorithm_vertgradient: gtk::RadioButton = builder.object("radio_button_similar_hash_algorithm_vertgradient").unwrap(); let radio_button_similar_hash_algorithm_doublegradient: gtk::RadioButton = builder.object("radio_button_similar_hash_algorithm_doublegradient").unwrap(); - let radio_button_similar_hash_size_4: gtk::RadioButton = builder.object("radio_button_similar_hash_size_4").unwrap(); let radio_button_similar_hash_size_8: gtk::RadioButton = builder.object("radio_button_similar_hash_size_8").unwrap(); let radio_button_similar_hash_size_16: gtk::RadioButton = builder.object("radio_button_similar_hash_size_16").unwrap(); + let radio_button_similar_hash_size_32: gtk::RadioButton = builder.object("radio_button_similar_hash_size_32").unwrap(); + let radio_button_similar_hash_size_64: gtk::RadioButton = builder.object("radio_button_similar_hash_size_64").unwrap(); + + radio_button_similar_hash_size_8.set_tooltip_text(Some("Default hash size, with very high similarity it produce quite good results and don't save too much data too cache.")); + radio_button_similar_hash_size_16.set_tooltip_text(Some("More precise than 8, so can be used to find very similar pictures, but create bigger cache entries.")); + radio_button_similar_hash_size_32.set_tooltip_text(Some("Hash of this size provide very big similarity which is more than enough for most usages.")); + radio_button_similar_hash_size_64.set_tooltip_text(Some("Paranoid mode, such tool create really big cache files and will catch almost same images.")); + + let label_similar_images_minimal_similarity: gtk::Label = builder.object("label_similar_images_minimal_similarity").unwrap(); let image_preview_similar_images: gtk::Image = builder.object("image_preview_similar_images").unwrap(); let image_preview_duplicates: gtk::Image = builder.object("image_preview_duplicates").unwrap(); @@ -268,9 +283,11 @@ impl GuiMainNotebook { radio_button_similar_hash_algorithm_mean, radio_button_similar_hash_algorithm_vertgradient, radio_button_similar_hash_algorithm_doublegradient, - radio_button_similar_hash_size_4, radio_button_similar_hash_size_8, radio_button_similar_hash_size_16, + radio_button_similar_hash_size_32, + radio_button_similar_hash_size_64, + label_similar_images_minimal_similarity, image_preview_similar_images, entry_duplicate_maximal_size, entry_same_music_maximal_size, diff --git a/czkawka_gui/ui/main_window.glade b/czkawka_gui/ui/main_window.glade index bd26a00..8180280 100644 --- a/czkawka_gui/ui/main_window.glade +++ b/czkawka_gui/ui/main_window.glade @@ -1315,22 +1315,6 @@ Author: Rafał Mikrut 0 - - - 4 - True - True - False - True - True - radio_button_similar_hash_size_8 - - - False - True - 1 - - 8 @@ -1362,6 +1346,36 @@ Author: Rafał Mikrut 3 + + + 32 + True + True + False + True + radio_button_similar_hash_size_8 + + + False + True + 4 + + + + + 64 + True + True + False + True + radio_button_similar_hash_size_8 + + + False + True + 5 + + False @@ -1496,7 +1510,7 @@ Author: Rafał Mikrut - + True False Minimal