1
0
Fork 0
mirror of synced 2024-04-27 01:02:23 +12:00

Add better custom selecting (#479)

This commit is contained in:
Rafał Mikrut 2021-12-02 15:33:06 +01:00 committed by GitHub
parent bb428171cb
commit f334bd6975
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 115 additions and 62 deletions

View file

@ -382,10 +382,11 @@ fn parse_similar_hash_algorithm(src: &str) -> Result<HashAlg, String> {
fn parse_image_hash_size(src: &str) -> Result<u8, String> {
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)
}

View file

@ -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::<usize>());
println!("cached - {}", records_already_cached.values().map(|e| e.len()).sum::<usize>());
// All results = records already cached + computed results
let mut save_cache_to_hashmap: BTreeMap<String, FileEntry> = Default::default();

View file

@ -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<String, FileEntry>, 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();

View file

@ -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");
}

View file

@ -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");
}

View file

@ -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) {

View file

@ -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 ");
});
}
}

View file

@ -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,

View file

@ -1315,22 +1315,6 @@ Author: Rafał Mikrut
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="radio_button_similar_hash_size_4">
<property name="label" translatable="yes">4</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="active">True</property>
<property name="draw-indicator">True</property>
<property name="group">radio_button_similar_hash_size_8</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="radio_button_similar_hash_size_8">
<property name="label" translatable="yes">8</property>
@ -1362,6 +1346,36 @@ Author: Rafał Mikrut
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="radio_button_similar_hash_size_32">
<property name="label" translatable="yes">32</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="draw-indicator">True</property>
<property name="group">radio_button_similar_hash_size_8</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="radio_button_similar_hash_size_64">
<property name="label" translatable="yes">64</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="draw-indicator">True</property>
<property name="group">radio_button_similar_hash_size_8</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -1496,7 +1510,7 @@ Author: Rafał Mikrut
</packing>
</child>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="label_similar_images_minimal_similarity">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes"> Minimal </property>