Add very small similarity level to finding similar images, add option to choose level from CLI, fix bug with duplicated entries in similar pictures (#104)
This commit is contained in:
parent
2815692205
commit
29a0716be5
|
@ -1,5 +1,6 @@
|
|||
use czkawka_core::duplicate::{CheckingMethod, DeleteMethod};
|
||||
use czkawka_core::same_music::MusicSimilarity;
|
||||
use czkawka_core::similar_images::Similarity;
|
||||
use std::path::PathBuf;
|
||||
use structopt::StructOpt;
|
||||
|
||||
|
@ -99,6 +100,8 @@ pub enum Commands {
|
|||
excluded_directories: ExcludedDirectories,
|
||||
#[structopt(short, long, parse(try_from_str = parse_minimal_file_size), default_value = "16384", help = "Minimum size in bytes", long_help = "Minimum size of checked files in bytes, assigning bigger value may speed up searching")]
|
||||
minimal_file_size: u64,
|
||||
#[structopt(short, long, default_value = "High", parse(try_from_str = parse_similar_images_similarity), help = "Similairty level (VerySmall, Small, Medium, High, Very High)", long_help = "Methods to choose similarity level of images which will be considered as duplicated.")]
|
||||
similarity: Similarity,
|
||||
#[structopt(flatten)]
|
||||
excluded_items: ExcludedItems,
|
||||
#[structopt(flatten)]
|
||||
|
@ -218,6 +221,17 @@ fn parse_delete_method(src: &str) -> Result<DeleteMethod, &'static str> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_similar_images_similarity(src: &str) -> Result<Similarity, &'static str> {
|
||||
match src.to_ascii_lowercase().replace('_', "").as_str() {
|
||||
"verysmall" => Ok(Similarity::VerySmall),
|
||||
"small" => Ok(Similarity::Small),
|
||||
"medium" => Ok(Similarity::Medium),
|
||||
"high" => Ok(Similarity::High),
|
||||
"veryhigh" => Ok(Similarity::VeryHigh),
|
||||
_ => Err("Couldn't parse the delete method (allowed: verysmall, small, medium, high, veryhigh)"),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_minimal_file_size(src: &str) -> Result<u64, String> {
|
||||
match src.parse::<u64>() {
|
||||
Ok(minimal_file_size) => {
|
||||
|
|
|
@ -199,6 +199,7 @@ fn main() {
|
|||
excluded_items,
|
||||
file_to_save,
|
||||
minimal_file_size,
|
||||
similarity,
|
||||
not_recursive,
|
||||
} => {
|
||||
let mut sf = SimilarImages::new();
|
||||
|
@ -208,6 +209,7 @@ fn main() {
|
|||
sf.set_excluded_items(path_list_to_str(excluded_items.excluded_items));
|
||||
sf.set_minimal_file_size(minimal_file_size);
|
||||
sf.set_recursive_search(!not_recursive.not_recursive);
|
||||
sf.set_similarity(similarity);
|
||||
|
||||
sf.find_similar_images(None);
|
||||
|
||||
|
|
|
@ -16,9 +16,10 @@ use std::io::Write;
|
|||
use std::path::PathBuf;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
|
||||
pub enum Similarity {
|
||||
None,
|
||||
VerySmall,
|
||||
Small,
|
||||
Medium,
|
||||
High,
|
||||
|
@ -320,7 +321,8 @@ impl SimilarImages {
|
|||
Similarity::High => 1,
|
||||
Similarity::Medium => 2,
|
||||
Similarity::Small => 3,
|
||||
_ => panic!("0-3 similarity levels are allowed, check if not added more."),
|
||||
Similarity::VerySmall => 4,
|
||||
_ => panic!("0-4 similarity levels are allowed, check if not added more."),
|
||||
};
|
||||
|
||||
// TODO
|
||||
|
@ -336,6 +338,11 @@ impl SimilarImages {
|
|||
if stop_receiver.is_some() && stop_receiver.unwrap().try_recv().is_ok() {
|
||||
return false;
|
||||
}
|
||||
if !hashes_to_check.contains_key(hash) {
|
||||
continue;
|
||||
}
|
||||
hashes_to_check.remove(hash);
|
||||
|
||||
let vector_with_found_similar_hashes = self.bktree.find(hash, similarity).collect::<Vec<_>>();
|
||||
if vector_with_found_similar_hashes.len() == 1 && vec_file_entry.len() == 1 {
|
||||
// This one picture doesn't have similar pictures, so there is no go
|
||||
|
@ -375,7 +382,8 @@ impl SimilarImages {
|
|||
1 => Similarity::High,
|
||||
2 => Similarity::Medium,
|
||||
3 => Similarity::Small,
|
||||
_ => panic!("0-3 similarity levels are allowed, check if not added more."),
|
||||
4 => Similarity::VerySmall,
|
||||
_ => panic!("0-4 similarity levels are allowed, check if not added more."),
|
||||
},
|
||||
})
|
||||
.collect::<Vec<_>>()),
|
||||
|
@ -503,6 +511,7 @@ impl PrintResults for SimilarImages {
|
|||
|
||||
fn get_string_from_similarity(similarity: &Similarity) -> &str {
|
||||
match similarity {
|
||||
Similarity::VerySmall => "Very Small",
|
||||
Similarity::Small => "Small",
|
||||
Similarity::Medium => "Medium",
|
||||
Similarity::High => "High",
|
||||
|
|
|
@ -1131,6 +1131,21 @@ Author: Rafał Mikrut
|
|||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="radio_button_similar_images_very_small">
|
||||
<property name="label" translatable="yes">Very Small</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_images_very_high</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_images_small">
|
||||
<property name="label" translatable="yes">Small</property>
|
||||
|
@ -1143,7 +1158,7 @@ Author: Rafał Mikrut
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -1158,7 +1173,7 @@ Author: Rafał Mikrut
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -1174,7 +1189,7 @@ Author: Rafał Mikrut
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -1189,7 +1204,7 @@ Author: Rafał Mikrut
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -32,6 +32,7 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender<Message>) {
|
|||
let radio_button_duplicates_size = gui_data.radio_button_duplicates_size.clone();
|
||||
let radio_button_duplicates_hashmb = gui_data.radio_button_duplicates_hashmb.clone();
|
||||
let radio_button_duplicates_hash = gui_data.radio_button_duplicates_hash.clone();
|
||||
let radio_button_similar_images_very_small = gui_data.radio_button_similar_images_very_small.clone();
|
||||
let radio_button_similar_images_small = gui_data.radio_button_similar_images_small.clone();
|
||||
let radio_button_similar_images_medium = gui_data.radio_button_similar_images_medium.clone();
|
||||
let radio_button_similar_images_high = gui_data.radio_button_similar_images_high.clone();
|
||||
|
@ -203,7 +204,9 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender<Message>) {
|
|||
};
|
||||
|
||||
let similarity;
|
||||
if radio_button_similar_images_small.get_active() {
|
||||
if radio_button_similar_images_very_small.get_active() {
|
||||
similarity = similar_images::Similarity::VerySmall;
|
||||
} else if radio_button_similar_images_small.get_active() {
|
||||
similarity = similar_images::Similarity::Small;
|
||||
} else if radio_button_similar_images_medium.get_active() {
|
||||
similarity = similar_images::Similarity::Medium;
|
||||
|
|
|
@ -103,6 +103,7 @@ pub struct GuiData {
|
|||
pub radio_button_duplicates_hashmb: gtk::RadioButton,
|
||||
pub radio_button_duplicates_hash: gtk::RadioButton,
|
||||
|
||||
pub radio_button_similar_images_very_small: gtk::RadioButton,
|
||||
pub radio_button_similar_images_small: gtk::RadioButton,
|
||||
pub radio_button_similar_images_medium: gtk::RadioButton,
|
||||
pub radio_button_similar_images_high: gtk::RadioButton,
|
||||
|
@ -286,6 +287,7 @@ impl GuiData {
|
|||
let radio_button_duplicates_hashmb: gtk::RadioButton = builder.get_object("radio_button_duplicates_hashmb").unwrap();
|
||||
let radio_button_duplicates_hash: gtk::RadioButton = builder.get_object("radio_button_duplicates_hash").unwrap();
|
||||
|
||||
let radio_button_similar_images_very_small: gtk::RadioButton = builder.get_object("radio_button_similar_images_very_small").unwrap();
|
||||
let radio_button_similar_images_small: gtk::RadioButton = builder.get_object("radio_button_similar_images_small").unwrap();
|
||||
let radio_button_similar_images_medium: gtk::RadioButton = builder.get_object("radio_button_similar_images_medium").unwrap();
|
||||
let radio_button_similar_images_high: gtk::RadioButton = builder.get_object("radio_button_similar_images_high").unwrap();
|
||||
|
@ -391,6 +393,7 @@ impl GuiData {
|
|||
radio_button_duplicates_size,
|
||||
radio_button_duplicates_hashmb,
|
||||
radio_button_duplicates_hash,
|
||||
radio_button_similar_images_very_small,
|
||||
radio_button_similar_images_small,
|
||||
radio_button_similar_images_medium,
|
||||
radio_button_similar_images_high,
|
||||
|
|
|
@ -221,6 +221,7 @@ pub fn hide_all_buttons_except(except_name: &str, buttons_array: &[gtk::Button],
|
|||
pub fn get_text_from_similarity(similarity: &Similarity) -> &str {
|
||||
match similarity {
|
||||
Similarity::None => "Original",
|
||||
Similarity::VerySmall => "Very Small",
|
||||
Similarity::Small => "Small",
|
||||
Similarity::Medium => "Medium",
|
||||
Similarity::High => "High",
|
||||
|
|
Loading…
Reference in a new issue