1
0
Fork 0
mirror of synced 2024-05-05 13:03:02 +12:00

Add button to ignore images with non unique size. (#493)

This will help with finding different images(non 1:1 which could be easily found by duplicate finder tool)
This commit is contained in:
Rafał Mikrut 2021-12-08 23:08:05 +01:00 committed by GitHub
parent 457b55ada5
commit 5f774e03bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 50 additions and 8 deletions

View file

@ -10,8 +10,6 @@
- Cache support - second and further scans should be a lot faster than the first one - Cache support - second and further scans should be a lot faster than the first one
- CLI frontend - for easy automation - CLI frontend - for easy automation
- GUI frontend - uses modern GTK 3 and looks similar to FSlint - GUI frontend - uses modern GTK 3 and looks similar to FSlint
- Rich search option - allows setting absolute included and excluded directories, set of allowed file extensions
or excluded items with the `*` wildcard
- No spying - Czkawka does not have access to the Internet, nor does it collect any user information or statistics - No spying - Czkawka does not have access to the Internet, nor does it collect any user information or statistics
- Multiple tools to use: - Multiple tools to use:
- Duplicates - Finds duplicates based on file name, size or hash - Duplicates - Finds duplicates based on file name, size or hash
@ -26,7 +24,7 @@
- Broken Files - Finds files with an invalid extension or that are corrupted - Broken Files - Finds files with an invalid extension or that are corrupted
<!-- The GIF thingy --> <!-- The GIF thingy -->
![Czkawka](https://user-images.githubusercontent.com/41945903/104711404-9cbb7400-5721-11eb-904d-9677c189f7ab.gif) ![Czkawka](https://user-images.githubusercontent.com/41945903/145280350-506f7e94-4db0-4de7-a68d-6e7c26bbd2bf.gif)
## How do I use it? ## How do I use it?
You can find the instructions on how to use Czkawka [**here**](instructions/Instruction.md). You can find the instructions on how to use Czkawka [**here**](instructions/Instruction.md).

View file

@ -101,6 +101,7 @@ pub struct SimilarImages {
image_filter: FilterType, image_filter: FilterType,
use_cache: bool, use_cache: bool,
delete_outdated_cache: bool, delete_outdated_cache: bool,
exclude_images_with_same_size: bool,
} }
/// Info struck with helpful information's about results /// Info struck with helpful information's about results
@ -140,6 +141,7 @@ impl SimilarImages {
image_filter: FilterType::Lanczos3, image_filter: FilterType::Lanczos3,
use_cache: true, use_cache: true,
delete_outdated_cache: true, delete_outdated_cache: true,
exclude_images_with_same_size: false,
} }
} }
@ -156,6 +158,10 @@ impl SimilarImages {
self.delete_outdated_cache = delete_outdated_cache; self.delete_outdated_cache = delete_outdated_cache;
} }
pub fn set_exclude_images_with_same_size(&mut self, exclude_images_with_same_size: bool) {
self.exclude_images_with_same_size = exclude_images_with_same_size;
}
pub fn set_hash_alg(&mut self, hash_alg: HashAlg) { pub fn set_hash_alg(&mut self, hash_alg: HashAlg) {
self.hash_alg = hash_alg; self.hash_alg = hash_alg;
} }
@ -384,6 +390,21 @@ impl SimilarImages {
fn sort_images(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::UnboundedSender<ProgressData>>) -> bool { fn sort_images(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::UnboundedSender<ProgressData>>) -> bool {
let hash_map_modification = SystemTime::now(); let hash_map_modification = SystemTime::now();
if self.exclude_images_with_same_size {
let mut old_hash_map = Default::default();
mem::swap(&mut self.images_to_check, &mut old_hash_map);
let mut new_hash_map: BTreeMap<u64, FileEntry> = Default::default();
for (_name, file_entry) in old_hash_map {
new_hash_map.insert(file_entry.size, file_entry);
}
self.images_to_check = Default::default();
for (_size, file_entry) in new_hash_map {
self.images_to_check.insert(file_entry.path.to_string_lossy().to_string(), file_entry);
}
}
let loaded_hash_map; let loaded_hash_map;
let mut records_already_cached: BTreeMap<String, FileEntry> = Default::default(); let mut records_already_cached: BTreeMap<String, FileEntry> = Default::default();
@ -736,10 +757,6 @@ impl PrintResults for SimilarImages {
pub fn save_hashes_to_file(hashmap: &BTreeMap<String, FileEntry>, text_messages: &mut Messages, hash_size: u8, hash_alg: HashAlg, image_filter: FilterType) { pub fn save_hashes_to_file(hashmap: &BTreeMap<String, FileEntry>, text_messages: &mut Messages, hash_size: u8, hash_alg: HashAlg, image_filter: FilterType) {
if let Some(proj_dirs) = ProjectDirs::from("pl", "Qarmin", "Czkawka") { if let Some(proj_dirs) = ProjectDirs::from("pl", "Qarmin", "Czkawka") {
// Lin: /home/username/.cache/czkawka
// Win: C:\Users\Username\AppData\Local\Qarmin\Czkawka\cache
// Mac: /Users/Username/Library/Caches/pl.Qarmin.Czkawka
let cache_dir = PathBuf::from(proj_dirs.cache_dir()); let cache_dir = PathBuf::from(proj_dirs.cache_dir());
if cache_dir.exists() { if cache_dir.exists() {
if !cache_dir.is_dir() { if !cache_dir.is_dir() {

View file

@ -39,6 +39,7 @@ pub fn connect_button_search(
futures_sender_broken_files: futures::channel::mpsc::UnboundedSender<broken_files::ProgressData>, futures_sender_broken_files: futures::channel::mpsc::UnboundedSender<broken_files::ProgressData>,
) { ) {
let buttons_array = gui_data.bottom_buttons.buttons_array.clone(); let buttons_array = gui_data.bottom_buttons.buttons_array.clone();
let check_button_image_ignore_same_size = gui_data.main_notebook.check_button_image_ignore_same_size.clone();
let buttons_names = gui_data.bottom_buttons.buttons_names.clone(); let buttons_names = gui_data.bottom_buttons.buttons_names.clone();
let buttons_search_clone = gui_data.bottom_buttons.buttons_search.clone(); let buttons_search_clone = gui_data.bottom_buttons.buttons_search.clone();
let check_button_duplicates_use_prehash_cache = gui_data.settings.check_button_duplicates_use_prehash_cache.clone(); let check_button_duplicates_use_prehash_cache = gui_data.settings.check_button_duplicates_use_prehash_cache.clone();
@ -344,6 +345,8 @@ pub fn connect_button_search(
let minimal_file_size = entry_similar_images_minimal_size.text().as_str().parse::<u64>().unwrap_or(1024 * 16); let minimal_file_size = entry_similar_images_minimal_size.text().as_str().parse::<u64>().unwrap_or(1024 * 16);
let maximal_file_size = entry_similar_images_maximal_size.text().as_str().parse::<u64>().unwrap_or(1024 * 1024 * 1024 * 1024); let maximal_file_size = entry_similar_images_maximal_size.text().as_str().parse::<u64>().unwrap_or(1024 * 1024 * 1024 * 1024);
let ignore_same_size = check_button_image_ignore_same_size.is_active();
let similarity = similar_images::Similarity::Similar(scale_similarity_similar_images.value() as u32); let similarity = similar_images::Similarity::Similar(scale_similarity_similar_images.value() as u32);
let delete_outdated_cache = check_button_settings_similar_images_delete_outdated_cache.is_active(); let delete_outdated_cache = check_button_settings_similar_images_delete_outdated_cache.is_active();
@ -365,6 +368,7 @@ pub fn connect_button_search(
sf.set_hash_size(hash_size); sf.set_hash_size(hash_size);
sf.set_image_filter(image_filter); sf.set_image_filter(image_filter);
sf.set_delete_outdated_cache(delete_outdated_cache); sf.set_delete_outdated_cache(delete_outdated_cache);
sf.set_exclude_images_with_same_size(ignore_same_size);
sf.find_similar_images(Some(&stop_receiver), Some(&futures_sender_similar_images)); sf.find_similar_images(Some(&stop_receiver), Some(&futures_sender_similar_images));
let _ = glib_stop_sender.send(Message::SimilarImages(sf)); let _ = glib_stop_sender.send(Message::SimilarImages(sf));
}); });

View file

@ -89,6 +89,8 @@ pub struct GuiMainNotebook {
pub radio_button_similar_hash_size_32: gtk::RadioButton, pub radio_button_similar_hash_size_32: gtk::RadioButton,
pub radio_button_similar_hash_size_64: gtk::RadioButton, pub radio_button_similar_hash_size_64: gtk::RadioButton,
pub check_button_image_ignore_same_size: gtk::CheckButton,
pub label_similar_images_minimal_similarity: gtk::Label, pub label_similar_images_minimal_similarity: gtk::Label,
pub image_preview_similar_images: gtk::Image, pub image_preview_similar_images: gtk::Image,
@ -218,6 +220,8 @@ impl GuiMainNotebook {
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_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.")); 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 check_button_image_ignore_same_size: gtk::CheckButton = builder.object("check_button_image_ignore_same_size").unwrap();
let label_similar_images_minimal_similarity: gtk::Label = builder.object("label_similar_images_minimal_similarity").unwrap(); 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_similar_images: gtk::Image = builder.object("image_preview_similar_images").unwrap();
@ -290,6 +294,7 @@ impl GuiMainNotebook {
radio_button_similar_hash_size_16, radio_button_similar_hash_size_16,
radio_button_similar_hash_size_32, radio_button_similar_hash_size_32,
radio_button_similar_hash_size_64, radio_button_similar_hash_size_64,
check_button_image_ignore_same_size,
label_similar_images_minimal_similarity, label_similar_images_minimal_similarity,
image_preview_similar_images, image_preview_similar_images,
entry_duplicate_maximal_size, entry_duplicate_maximal_size,

View file

@ -753,5 +753,9 @@ fn show_preview(tree_view: &TreeView, text_view_errors: &TextView, check_button_
image_preview_similar_images.show(); image_preview_similar_images.show();
} else { } else {
image_preview_similar_images.hide(); image_preview_similar_images.hide();
{
let mut preview_path = preview_path.borrow_mut();
*preview_path = "".to_string();
}
} }
} }

View file

@ -1438,7 +1438,7 @@ Author: Rafał Mikrut
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">4</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -1453,6 +1453,20 @@ Author: Rafał Mikrut
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_image_ignore_same_size">
<property name="label" translatable="yes">Ignore same size</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property> <property name="position">5</property>
</packing> </packing>
</child> </child>