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:
parent
457b55ada5
commit
5f774e03bd
|
@ -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).
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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));
|
||||||
});
|
});
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue