diff --git a/image_list.py b/image_list.py index f182cf7..8a18cdf 100755 --- a/image_list.py +++ b/image_list.py @@ -41,7 +41,10 @@ def setup_options(): parser.add_argument("--small",action="store_true",dest="searchsmall",default=False, help="Return a list of small files, smaller than -m INT. This option will flip the 'Add new files' option. [%(default)s]") parser.add_argument("--similar",type=str,dest="similarity",default=None, - help="Search list for similar images. Value 0-255 for similarity threshold. 0=high similarity. If value is a filename, search similar to that image.") + help="Search list for similar images. Value 0-255 for similarity threshold. 0=high similarity. "+ + "If value is a filename, search similar to that image.") + parser.add_argument("--viewer",type=str,dest="viewer",default=None, + help="Program to view images, %%f refers to filename(s)") parser.add_argument("-x",action="append",dest="exclude",default=[], help="Exclude folder name from the lists. This option may be issued several times") parser.add_argument('startpath', action="store",default='.', nargs='?') @@ -308,40 +311,65 @@ def get_fingerprint(filename): values+='0' return str(int(values,2)) -def find_fingerprint_similar(sqlfile,thr): +def find_fingerprint_similar(opts): ''' Find all similar images, nearest match more similar than thr ''' - conn=sqlite3.connect(sqlfile) + + thr=int(opts.similarity) + conn=sqlite3.connect(opts.sqlfile) conn.text_factory=str db1=conn.cursor() db2=conn.cursor() - db1.execute("SELECT file,fingerprint,width,height FROM list ORDER BY file") + db1.execute("SELECT file,fingerprint,sharpness,width,height,R,G,B FROM list WHERE sharpness > 0 ORDER BY file") hits=[] + hit_list=[] for i,hit1 in enumerate(db1): - if hit1[0] in hits: + if hit1[0] in hit_list: continue - this=[hit1[0],'',sys.maxint,int(hit1[1]),hit1[2]*hit1[3]] - db2.execute("SELECT file,fingerprint,width,height FROM list ORDER BY file") + cmp=hit1[0] + fp=int(hit1[1]) + sp=hit1[2] + dims=hit1[3:5] + pixels=dims[0]*dims[1] + colors=hit1[5:8] + db2.execute("SELECT file,fingerprint,sharpness,width,height,R,G,B FROM list WHERE sharpness > 0 ORDER BY file") + this1=[ [cmp, 0,sp,int(hit1[3]),int(hit1[4]),0,pixels] ] for hit2 in db2: - if hit2[0]==this[0]: + if hit2[0]==cmp: continue - similarity=bin(this[3]^int(hit2[1])).count('1') + similarity=bin(fp^int(hit2[1])).count('1') if similarity1: + hits.append(this1) + hit_list.append(cmp) + + if i==0: + print("No measurements found") + sys.exit(1) + + for src in hits: + file_len=str(max([len(x[0]) for x in src])) + print( ('{: <'+file_len+'} {: >4} {: >4} {: >4} {: ^5}x{: ^5}').format("File","Diff","CDel","Shrp","Wth","Hgt")) + for c in range(len(src)): + print( ('{: <'+file_len+'} {: >4} {: >4} {: >4} {: >5}x{: >5}').format(src[c][0],src[c][1],"%.2f"%src[c][5], + "%.1f" % src[c][2],src[c][3],src[c][4])) + if opts.viewer: + fnames=[x[0] for x in src] + subprocess.call(opts.viewer.replace('%f', " ".join(fnames)), shell=True) + return -def find_fingerprint_nearest(sqlfile,cmp): - ''' Find nearest match ''' - cmp=os.path.abspath(cmp) - conn=sqlite3.connect(sqlfile) +def find_fingerprint_nearest(opts): + ''' Find nearest match to given file ''' + + cmp=os.path.abspath(opts.similarity) + conn=sqlite3.connect(opts.sqlfile) conn.text_factory=str db1=conn.cursor() if is_listed(db1, cmp): @@ -377,6 +405,10 @@ def find_fingerprint_nearest(sqlfile,cmp): print( ('{: <'+file_len+'} {: >4} {: >4} {: >4} {: ^5}x{: ^5}').format("File","Diff","CDel","Shrp","Wth","Hgt")) print( ('{: <'+file_len+'} {: >4} {: >4} {: >4} {: >5}x{: >5}').format(cmp,"","","%.1f" % sp,dims[0],dims[1])) print( ('{: <'+file_len+'} {: >4} {: >4} {: >4} {: >5}x{: >5}').format(this[0], this[1],"%.2f"%this[5], "%.1f" % this[2],this[3], this[4])) + + if opts.viewer: + subprocess.call(opts.viewer.replace('%f', " ".join((cmp,this[0]))), stderr=subprocess.STDOUT, shell=True) + def append_sharpness(sqlfile): conn=sqlite3.connect(sqlfile) @@ -511,7 +543,7 @@ def print_structure(files): i+=1 return -def print_dup_structure(files): +def print_dup_structure(files,opts): i=1 for hash in files: #print(hash[0]) @@ -519,6 +551,9 @@ def print_dup_structure(files): for f in hash[1]: fnames.append(' "'+f[0]+'"') print "%(i)d:%(n)d:%(f)s " % {'i':i, 'n':len(fnames), 'f':",".join(fnames)} + if opts.viewer: + fnames=[x[0] for x in hash[1]] + subprocess.call(opts.viewer.replace('%f', " ".join(fnames)), shell=True) i+=1 return @@ -548,12 +583,12 @@ def main(): find_color_nearest(options.sqlfile,options.nearestcolor) if options.similarity!=None: if os.path.exists(options.similarity): - find_fingerprint_nearest(options.sqlfile,options.similarity) + find_fingerprint_nearest(options) else: - find_fingerprint_similar(options.sqlfile,int(options.similarity)) + find_fingerprint_similar(options) if options.duplicate: files=find_duplicates(options.sqlfile,options.startpath) - print_dup_structure(files) + print_dup_structure(files,options) if options.searchsmall: files=find_smalls(options.minsize,options.sqlfile) if options.deleteFiles: