2
2
3
3
####################################################################################
4
4
#
5
- # Copyright (c) 2022-2024 Piotr Jochymek
5
+ # Copyright (c) 2022-2025 Piotr Jochymek
6
6
#
7
7
# MIT License
8
8
#
@@ -247,8 +247,6 @@ def __init__(self,tkwindow):
247
247
from threading import Thread
248
248
from queue import Queue
249
249
250
- print ('Image_Cache init' )
251
-
252
250
self .paths_queue = Queue ()
253
251
self .scaled_images_data_queue = Queue ()
254
252
@@ -421,7 +419,6 @@ def eternal_photo_imagination(self,tkwindow):
421
419
###############################################################
422
420
423
421
def end (self ):
424
- print ('Image_Cache END' )
425
422
self .init_all ()
426
423
self .threads_keeep_looping = False
427
424
@@ -737,7 +734,7 @@ def preview_xscrollcommand(self,v1,v2):
737
734
self .preview_text_hbar .set (v1 ,v2 )
738
735
self .preview_text_hbar .grid (row = 1 ,column = 0 ,sticky = 'we' )
739
736
740
- def __init__ (self ,cwd ,paths_to_add = None ,exclude = None ,exclude_regexp = None ,norun = None ,images_mode_tuple = None ):
737
+ def __init__ (self ,cwd ,paths_to_add = None ,exclude = None ,exclude_regexp = None ,norun = None ,images_mode_tuple = None , size_min_str = 0 , size_max_str = 0 ):
741
738
images ,ihash ,idivergence ,rotations ,imin ,imax ,igps = images_mode_tuple if images_mode_tuple else (False ,0 ,0 ,False ,0 ,0 ,False )
742
739
743
740
gc_disable ()
@@ -1375,6 +1372,18 @@ def self_folder_tree_yview(*args):
1375
1372
self .exclude_frame .grid_rowconfigure (99 , weight = 1 )
1376
1373
##############
1377
1374
1375
+ self .file_min_size_check_var = BooleanVar ()
1376
+ self .file_max_size_check_var = BooleanVar ()
1377
+
1378
+ self .file_min_size_var = StringVar ()
1379
+ self .file_max_size_var = StringVar ()
1380
+
1381
+ self .file_min_size_var .set (size_min_str )
1382
+ self .file_max_size_var .set (size_max_str )
1383
+
1384
+ self .file_min_size_check_var .set (bool (size_min_str ))
1385
+ self .file_max_size_check_var .set (bool (size_max_str ))
1386
+
1378
1387
operation_mode_frame = LabelFrame (self_scan_dialog_area_main ,text = 'Operation mode' ,borderwidth = 2 ,bg = bg_color ,takefocus = False )
1379
1388
operation_mode_frame .grid (row = 3 ,column = 0 ,sticky = 'news' ,padx = 4 ,pady = 4 ,columnspan = 4 )
1380
1389
@@ -1391,12 +1400,46 @@ def self_folder_tree_yview(*args):
1391
1400
gps_button = Radiobutton (operation_mode_frame ,text = 'Images GPS data proximity' ,variable = self .operation_mode_var ,value = MODE_GPS ,command = self .operation_mode_change )
1392
1401
gps_button .grid (row = 0 ,column = 2 ,sticky = 'news' ,padx = 8 ,pady = 3 )
1393
1402
1403
+ gps_button .columnconfigure ( (0 ,1 ,2 ), weight = 1 , uniform = 2 )
1404
+
1394
1405
self .widget_tooltip (gps_button ,"Only image files with EXIF GPS\n data are processed. Identified groups\n contain images with GPS coordinates\n with close proximity to each other" )
1395
1406
1396
1407
operation_mode_frame .grid_columnconfigure ( (0 ,1 ,2 ), weight = 1 )
1397
1408
1409
+ temp_frame3a = LabelFrame (self_scan_dialog_area_main ,text = 'File size range' ,borderwidth = 2 ,bg = bg_color ,takefocus = False )
1410
+ temp_frame3a .grid (row = 4 ,column = 0 ,sticky = 'news' ,padx = 4 ,pady = 4 ,columnspan = 4 )
1411
+
1412
+ self .file_min_check = Checkbutton (temp_frame3a , text = 'Min:' , variable = self .file_min_size_check_var ,command = self .use_size_min_change_file )
1413
+ self .file_min_check .grid (row = 0 ,column = 0 ,padx = 4 ,pady = 4 , sticky = 'wens' )
1414
+
1415
+ self .file_min_Entry = Entry (temp_frame3a , textvariable = self .file_min_size_var ,width = 10 )
1416
+ self .file_min_Entry .grid (row = 0 ,column = 1 ,sticky = 'news' ,padx = 2 ,pady = 2 )
1417
+
1418
+ self .file_min_Space = Label (temp_frame3a )
1419
+ self .file_min_Space .grid (row = 0 ,column = 2 ,sticky = 'news' ,padx = 2 ,pady = 2 )
1420
+
1421
+ self .file_max_check = Checkbutton (temp_frame3a , text = 'Max:' , variable = self .file_max_size_check_var ,command = self .use_size_max_change_file )
1422
+ self .file_max_check .grid (row = 0 ,column = 3 ,padx = 4 ,pady = 4 , sticky = 'wens' )
1423
+
1424
+ self .file_max_Entry = Entry (temp_frame3a , textvariable = self .file_max_size_var ,width = 10 )
1425
+ self .file_max_Entry .grid (row = 0 ,column = 4 ,sticky = 'news' ,padx = 2 ,pady = 2 )
1426
+
1427
+ self .file_max_Space = Label (temp_frame3a )
1428
+ self .file_max_Space .grid (row = 0 ,column = 5 ,sticky = 'news' ,padx = 2 ,pady = 2 )
1429
+
1430
+ temp_frame3a .grid_columnconfigure ((2 ,5 ), weight = 1 )
1431
+
1432
+ size_min_tooltip = "Limit the search pool to files with\n size equal or greater to the specified\n (e.g. 112kB, 1MB ...)"
1433
+ size_max_tooltip = "Limit the search pool to files with\n size smaller or equal to the specified\n (e.g. 10MB, 1GB ...)"
1434
+ self .widget_tooltip (self .file_min_check ,size_min_tooltip )
1435
+ self .widget_tooltip (self .file_min_Entry ,size_min_tooltip )
1436
+
1437
+ self .widget_tooltip (self .file_max_check ,size_max_tooltip )
1438
+ self .widget_tooltip (self .file_max_Entry ,size_max_tooltip )
1439
+
1440
+
1398
1441
temp_frame3 = LabelFrame (self_scan_dialog_area_main ,text = 'Similarity mode options' ,borderwidth = 2 ,bg = bg_color ,takefocus = False )
1399
- temp_frame3 .grid (row = 4 ,column = 0 ,sticky = 'news' ,padx = 4 ,pady = 4 ,columnspan = 4 )
1442
+ temp_frame3 .grid (row = 5 ,column = 0 ,sticky = 'news' ,padx = 4 ,pady = 4 ,columnspan = 4 )
1400
1443
1401
1444
sf_par3 = Frame (temp_frame3 ,bg = bg_color )
1402
1445
sf_par3 .pack (fill = 'both' ,expand = True ,side = 'top' )
@@ -1460,17 +1503,27 @@ def self_folder_tree_yview(*args):
1460
1503
size_range_frame = LabelFrame (sf_par3 ,text = 'Image size range (pixels)' ,borderwidth = 2 ,bg = bg_color ,takefocus = False )
1461
1504
size_range_frame .grid (row = 2 ,column = 0 ,padx = 2 ,sticky = 'news' ,columnspan = 2 )
1462
1505
1463
- self .image_min_check = Checkbutton (size_range_frame , text = 'Min size :' , variable = self .image_min_size_check_var ,command = self .use_size_min_change )
1506
+ self .image_min_check = Checkbutton (size_range_frame , text = 'Min:' , variable = self .image_min_size_check_var ,command = self .use_size_min_change )
1464
1507
self .image_min_check .grid (row = 0 ,column = 0 ,padx = 4 ,pady = 4 , sticky = 'wens' )
1465
1508
1466
1509
self .image_min_Entry = Entry (size_range_frame , textvariable = self .image_min_size_var ,width = 10 )
1467
1510
self .image_min_Entry .grid (row = 0 ,column = 1 ,sticky = 'news' ,padx = 2 ,pady = 2 )
1468
1511
1469
- self .image_max_check = Checkbutton (size_range_frame , text = 'Max size:' , variable = self .image_max_size_check_var ,command = self .use_size_max_change )
1470
- self .image_max_check .grid (row = 0 ,column = 2 ,padx = 4 ,pady = 4 , sticky = 'wens' )
1512
+ self .image_min_Space = Label (size_range_frame )
1513
+ self .image_min_Space .grid (row = 0 ,column = 2 ,sticky = 'news' ,padx = 2 ,pady = 2 )
1514
+
1515
+
1516
+ self .image_max_check = Checkbutton (size_range_frame , text = 'Max:' , variable = self .image_max_size_check_var ,command = self .use_size_max_change )
1517
+ self .image_max_check .grid (row = 0 ,column = 3 ,padx = 4 ,pady = 4 , sticky = 'wens' )
1471
1518
1472
1519
self .image_max_Entry = Entry (size_range_frame , textvariable = self .image_max_size_var ,width = 10 )
1473
- self .image_max_Entry .grid (row = 0 ,column = 3 ,sticky = 'news' ,padx = 2 ,pady = 2 )
1520
+ self .image_max_Entry .grid (row = 0 ,column = 4 ,sticky = 'news' ,padx = 2 ,pady = 2 )
1521
+
1522
+ self .image_min_Space = Label (size_range_frame )
1523
+ self .image_min_Space .grid (row = 0 ,column = 5 ,sticky = 'news' ,padx = 2 ,pady = 2 )
1524
+
1525
+ size_range_frame .grid_columnconfigure ((2 ,5 ), weight = 1 )
1526
+
1474
1527
1475
1528
min_tooltip = "Limit the search pool to images with\n both dimensions (width and height)\n equal or greater to the specified value\n in pixels (e.g. 512)"
1476
1529
max_tooltip = "Limit the search pool to images with\n both dimensions (width and height)\n smaller or equal to the specified value\n in pixels (e.g. 4096)"
@@ -1706,6 +1759,12 @@ def use_size_min_change(self):
1706
1759
def use_size_max_change (self ):
1707
1760
self .image_max_Entry .configure (state = 'normal' if self .image_max_size_check_var .get () else 'disabled' )
1708
1761
1762
+ def use_size_min_change_file (self ):
1763
+ self .file_min_Entry .configure (state = 'normal' if self .file_min_size_check_var .get () else 'disabled' )
1764
+
1765
+ def use_size_max_change_file (self ):
1766
+ self .file_max_Entry .configure (state = 'normal' if self .file_max_size_check_var .get () else 'disabled' )
1767
+
1709
1768
def operation_mode_change (self ):
1710
1769
operation_mode = self .operation_mode_var .get ()
1711
1770
if operation_mode == MODE_CRC :
@@ -1752,6 +1811,9 @@ def operation_mode_change(self):
1752
1811
else :
1753
1812
print ('unknown operation_mode:' ,operation_mode )
1754
1813
1814
+ self .use_size_min_change_file ()
1815
+ self .use_size_max_change_file ()
1816
+
1755
1817
def distance_val_set (self ):
1756
1818
self .similarity_distance_var_lab .set (str (self .similarity_distance_var .get ())[:4 ])
1757
1819
@@ -3102,7 +3164,7 @@ def show_preview(self,user_action=True):
3102
3164
else :
3103
3165
self .preview_shown = True
3104
3166
3105
- if cfg_geometry := self .cfg_get ('preview' ,'200x200 ' ,section = 'geometry' ):
3167
+ if cfg_geometry := self .cfg_get ('preview' ,'800x600 ' ,section = 'geometry' ):
3106
3168
self_preview .geometry (cfg_geometry )
3107
3169
3108
3170
self_preview .deiconify ()
@@ -3898,7 +3960,7 @@ def scan(self):
3898
3960
try :
3899
3961
image_min_size_int = int (image_min_size )
3900
3962
except Exception as e :
3901
- self .get_info_dialog_on_scan ().show ('Min size value error' ,f'fix: "{ image_min_size } "' )
3963
+ self .get_info_dialog_on_scan ().show ('Image Min size value error' ,f'fix: "{ image_min_size } "' )
3902
3964
return
3903
3965
3904
3966
image_max_size_int = 0
@@ -3907,10 +3969,30 @@ def scan(self):
3907
3969
try :
3908
3970
image_max_size_int = int (image_max_size )
3909
3971
except Exception as e :
3910
- self .get_info_dialog_on_scan ().show ('Max size value error' ,f'fix: "{ image_max_size } "' )
3972
+ self .get_info_dialog_on_scan ().show ('Image Max size value error' ,f'fix: "{ image_max_size } "' )
3911
3973
return
3912
3974
3913
- scan_thread = Thread (target = lambda : dude_core .scan (operation_mode ),daemon = True )
3975
+ ##################
3976
+ file_min_size_int = 0
3977
+ if self .file_min_size_check_var .get ():
3978
+ if file_min_size := self .file_min_size_var .get ():
3979
+ file_min_size_int = str_to_bytes (file_min_size )
3980
+
3981
+ if file_min_size_int == - 1 :
3982
+ self .get_info_dialog_on_scan ().show ('File Min size value error' ,f'fix: "{ file_min_size } "' )
3983
+ return
3984
+
3985
+ file_max_size_int = 0
3986
+ if self .file_max_size_check_var .get ():
3987
+ if file_max_size := self .file_max_size_var .get ():
3988
+ file_max_size_int = str_to_bytes (file_max_size )
3989
+
3990
+ if file_max_size_int == - 1 :
3991
+ self .get_info_dialog_on_scan ().show ('File Max size value error' ,f'fix: "{ file_max_size } "' )
3992
+ return
3993
+ #################
3994
+
3995
+ scan_thread = Thread (target = lambda : dude_core .scan (operation_mode ,file_min_size_int ,file_max_size_int ),daemon = True )
3914
3996
scan_thread .start ()
3915
3997
3916
3998
self_progress_dialog_on_scan .lab_l1 .configure (text = 'Total space:' )
@@ -6764,7 +6846,26 @@ def show_homepage(self):
6764
6846
else :
6765
6847
images_mode_tuple .append (False )
6766
6848
6767
- Gui ( getcwd (),p_args .paths ,p_args .exclude ,p_args .exclude_regexp ,p_args .norun ,images_mode_tuple )
6849
+
6850
+ size_min = 0
6851
+ if p_args .sizemin :
6852
+ size_min_cand = str_to_bytes (p_args .sizemin [0 ])
6853
+ if size_min_cand == - 1 :
6854
+ print (f"cannot parse sizemin value:'{ p_args .sizemin [0 ]} '" )
6855
+ sys .exit (2 )
6856
+ else :
6857
+ size_min = p_args .sizemin [0 ]
6858
+
6859
+ size_max = 0
6860
+ if p_args .sizemax :
6861
+ size_max_cand = str_to_bytes (p_args .sizemax [0 ])
6862
+ if size_max_cand == - 1 :
6863
+ print (f"cannot parse sizemax value:'{ p_args .sizemax [0 ]} '" )
6864
+ sys .exit (2 )
6865
+ else :
6866
+ size_max = p_args .sizemax [0 ]
6867
+
6868
+ Gui ( getcwd (),p_args .paths ,p_args .exclude ,p_args .exclude_regexp ,p_args .norun ,images_mode_tuple ,size_min ,size_max )
6768
6869
6769
6870
except Exception as e_main :
6770
6871
print (e_main )
0 commit comments