diff --git a/image_list.py b/image_list.py index 8e85c96..a0c0cd0 100755 --- a/image_list.py +++ b/image_list.py @@ -962,12 +962,12 @@ def main(): if options.delete: print('Deleting entries...') delete_nonexisting(options.sqlfile) - if options.delete_data: - print('Deleting metadata...') - delete_data(options.sqlfile) if options.add or options.changed: print('Adding entries...') add_recurse(options) + if options.delete_data: + print('Deleting metadata...') + delete_data(options.sqlfile) if options.search: print_structure(searchdb(options.sqlfile,options.search)) if options.measure: diff --git a/image_list_tagger.py b/image_list_tagger.py new file mode 100755 index 0000000..eb1d196 --- /dev/null +++ b/image_list_tagger.py @@ -0,0 +1,154 @@ +#!/usr/bin/python +import sys,os +from Tkinter import * +import Image, ImageTk, math, ImageDraw +from argparse import ArgumentParser +import sqlite3 + +SQLFILE='list_of_images.sqlite' +IMGMATCH=re.compile('.*\.jpg$|.*\.jpeg$|.*\.png$|.*\.gif$',re.I) + +def setup_options(): + parser=ArgumentParser(description="Tag images in image_list") + parser.add_argument("-f",action="store",dest="sqlfile",default=SQLFILE, + help="SQL file name to use [%(default)s]") + parser.add_argument("-t",action="store",dest="tags",default="thisIsGood,thisIsBad", + help="Comma separated list of tags") + parser.add_argument('path', action="store",default='.', nargs='?') + + options=parser.parse_args() + options.tags=[x.strip() for x in options.tags.split(",")] + return options + + +class Click: + def __init__(self, image,tags,sqlfile): + + self.title="Tagger: "+os.path.basename(image) + self.root=Tk() + self.root.geometry("1024x768+220+0") + self.root.bind("", self._quit) + self.root.title(self.title) + + self.image = Image.open(image) + self.image_name = image + self.img_copy= self.image.copy() + self.pixels = self.img_copy.load() + self.background_image = ImageTk.PhotoImage(self.image) + + self.background = Label(self.root, image=self.background_image, cursor='cross') + self.background.pack(fill="both", expand=True, side="left") + self.background.bind('', self._resize_image) + + self.top=Toplevel(self.root) + self.top.bind("", self._quit) + self.tagTexts=['Next']+tags + self.tags=[] + for t in range(len(self.tagTexts)): + return_func=self._tag_button(t) + if t==0: + self.tags.append(Button(self.top,text="[n] "+self.tagTexts[t], command=return_func)) + self.root.bind("n", self._tag_key) + self.top.bind("n", self._tag_key) + continue + if t<10: + self.tags.append(Button(self.top,text="[%d] %s"%(t,self.tagTexts[t]), command=return_func)) + self.root.bind(str(t), self._tag_key) + self.top.bind(str(t), self._tag_key) + continue + self.tags.append(Button(self.top,text=self.tagTexts[t], command=return_func)) + for t in range(len(self.tagTexts)): + self.tags[t].pack(fill="both", side="top") + self.top.geometry("220x%d+0+0"%(self.root.winfo_screenheight()-150,)) + + self._resize_init() + + self._init_db(sqlfile) + + + self.root.mainloop() + + def _tag_key(self,event): + if event.keysym=="n": + event.keysym=0 + thisfunc=self._tag_button(int(event.keysym)) + thisfunc() + + def _tag_button(self,n): + def actual_value(x=n): + if x==0: + self._next(n) + return + self._add_tag(x) + return actual_value + + def _resize_image(self,event): + new_width = event.width + new_height = event.height + self.image = self.img_copy.resize((new_width, new_height)) + self.background_image = ImageTk.PhotoImage(self.image) + self.background.configure(image = self.background_image) + + def _resize_init(self): + event = self._get_max_size() + self.root.geometry("%dx%d+220+0"% (event.width, event.height)) + self._resize_image(event) + + def _get_max_size(self,refer_size=None): + """ return max size for image that fits the refer_size,. + otherwise, return max size for the screen """ + if refer_size: + refer_width=refer_size[0] + refer_height=refer_size[1] + else: + refer_width=int(float(self.root.winfo_screenwidth()-220)) + refer_height=self.root.winfo_screenheight()-100 + new_height=refer_height + new_width= int(float(self.img_copy.size[0])/float(self.img_copy.size[1])*new_height) + if new_width>refer_width: + new_width=refer_width + new_height=int(float(self.img_copy.size[1])/float(self.img_copy.size[0])*new_width) + event = type('eventclass', (object,), + {'width':new_width, 'height':new_height})() + return event + + def _quit(self,event): + self.root.destroy() + sys.exit(0) + + def _next(self,event): + self.root.destroy() + + def _add_tag(self,x): + self.db[0].execute("SELECT hash FROM list WHERE file = ?",( os.path.realpath( self.image_name), )) + hashes=self.db[0].fetchall() + if len(hashes)==0: + print("Image %s not in database!" % (self.image_name) ) + self._next(None) + return + self.db[0].execute("INSERT INTO tags (hash,tag) VALUES (?,?)",( hashes[0][0], self.tagTexts[x] )) + self.db[1].commit() + print("Added %s:%s"%(self.image_name,self.tagTexts[x])) + return + + def _init_db(self, sqlfile): + + if not os.path.exists(sqlfile): + print("Cannot find SQLite file: "+sqlfile) + sys.exit(1) + conn=sqlite3.connect(sqlfile) + conn.text_factory=str + db=conn.cursor() + self.db=[db,conn] + + +opt=setup_options() +if os.path.isfile(opt.path): + imagelist=[opt.path] +else: + imagelist=sorted([f for f in os.listdir(opt.path) if IMGMATCH.match(f)]) + +for i,l in enumerate(imagelist): + print("%s %d"%( l, len(imagelist)-i+1)) + clicker = Click(l,opt.tags,opt.sqlfile) +