class Black_Hole(Simulton): def __init__(self,x,y): self._image = PhotoImage(file='Black_Hole.gif') Simulton.__init__(self,x,y,self._image.width(),self._image.height()) self.radius = (self._image.height()/2)+((self._image.width()**2)/(8 * self._image.height())) def update(self, model): from hunter import Hunter result = set() for item in model.find(lambda item:isinstance(item, Prey) or isinstance(item,Hunter)): if self.contains(item): result.add(item) return result def contains(self,s): if not isinstance(s,tuple): s = (s.get_location()[0],s.get_location()[1]) return math.sqrt((self.get_location()[0] - s[0])**2 + (self.get_location()[1] - s[1])**2) <= self.radius def display(self,canvas): canvas.create_image(*self.get_location(),image=self._image)
def make_canvas(self): """ Criação do canvas para edição da máscara de correção """ h = Scrollbar(self.root, orient=HORIZONTAL) v = Scrollbar(self.root, orient=VERTICAL) self.canvas = Canvas(self.root, scrollregion=(0, 0, 1000, 1000), yscrollcommand=v.set, xscrollcommand=h.set) h['command'] = self.canvas.xview v['command'] = self.canvas.yview self.canvas.grid(column=0, row=0, sticky=(N,W,E,S)) h.grid(column=0, row=1, sticky=(W,E)) v.grid(column=1, row=0, sticky=(N,S)) self.root.grid_columnconfigure(0, weight=1) self.root.grid_rowconfigure(0, weight=1) if self.image: imgtk = PhotoImage(image=Image.open(self.image)) # not file=imgpath imgwide = imgtk.width() # size in pixels imghigh = imgtk.height() # same as imgpil.size fullsize = (0, 0, imgwide, imghigh) # scrollable self.canvas.delete('all') # clear prior photo self.canvas.config(height=imgwide, width=imghigh) # viewable window size self.canvas.config(scrollregion=fullsize) # scrollable area size self.imageid=self.canvas.create_image(0, 0, image=imgtk, anchor=NW) self.images.append(imgtk) self.canvas.bind("<Button-1>", self.xy) self.canvas.bind("<B1-Motion>", self.add_rectangle) self.canvas.bind("<B1-ButtonRelease>", self.done_stroke) self.canvas.bind_all('<Button-2>', self.select) self.canvas.bind_all('<B2-Motion>', self.on_drag) self.canvas.bind_all("<B2-ButtonRelease>", self.update_item) self.canvas.bind('<Button-3>', self.config_item) self.canvas.bind_all('<Delete>',self.delete_item) self.canvas.focus()
def drawImage(self, imgpil, forcesize=()): """ 将图片绘制在窗体的canvas中 """ imgtk = PhotoImage(image=imgpil) # not file=imgpath scrwide, scrhigh = forcesize or self.maxsize() # wm screen size x,y #设置窗口显示的宽高 imgwide = imgtk.width() # size in pixels #图片的宽高 imghigh = imgtk.height() # same as imgpil.size fullsize = (0, 0, imgwide, imghigh) # scrollable #画布总区域 viewwide = min(imgwide, scrwide) # viewable #画布显示区域 viewhigh = min(imghigh, scrhigh) canvas = self.canvas canvas.delete('all') # clear prior photo #删除画布上之前的图像 canvas.config(height=viewhigh, width=viewwide) # viewable window size #设置画布显示的区域大小 canvas.config(scrollregion=fullsize) # scrollable area size #设置画布可滚动区域总大小 canvas.create_image(0, 0, image=imgtk, anchor=NW) #生成并显示图片并设置图片对齐方式 if imgwide <= scrwide and imghigh <= scrhigh: # too big for display? #图片大小比窗体大小小的话则打开窗体大小为普通 self.state('normal') # no: win size per img elif sys.platform[:3] == 'win': # do windows fullscreen#否则若为windows系统则使窗体全屏 self.state('zoomed') # others use geometry() self.saveimage = imgpil #PIL.Image类型 self.savephoto = imgtk # keep reference on me #PIL.ImageTk.PhotoImage,保持图片引用 trace((scrwide, scrhigh), imgpil.size)
def pil_image_dir(): from PIL.ImageTk import PhotoImage imgdir = 'images' if len(sys.argv) > 1: imgdir = sys.argv[1] imgfiles = os.listdir(imgdir) main = Tk() main.title('Image Viewer') quit = Button( main, text='Quit all', command=main.quit, font=('courier', 25)) quit.pack() savephotos = [] for imgfile in imgfiles: imgpath = os.path.join(imgdir, imgfile) win = Toplevel() win.title(imgfile) try: imgobj = PhotoImage(file=imgpath) Label(win, image=imgobj).pack() print(imgpath, imgobj.width(), imgobj.height()) savephotos.append(imgobj) except Exception: errmsg = 'skipping %s\n%s' % (imgfile, sys.exc_info()[1]) Label(win, text=errmsg).pack() main.mainloop()
def __init__(self, imgdir, imgfile): Toplevel.__init__(self) self.title(imgfile) imgpath = os.path.join(imgdir, imgfile) imgobj = PhotoImage(file=imgpath) Label(self, image = imgobj).pack() print(imgpath, imgobj.width(), imgobj.height()) self.savephoto = imgobj #Keep reference on me
def image_canvas_simple(): win = Tk() img = PhotoImage(file=gifdir+'ora-lp4e.gif') can = Canvas(win) can.pack(fill=BOTH) can.config(width=img.width(), height=img.height()) can.create_image(2, 2, image=img, anchor=NW) win.mainloop()
class Pulsator(Black_Hole): counter = 30 death = 15 def __init__(self,x,y,size = 30): Black_Hole.__init__(self,x,y) self.set_dimension(size, size) self._image = PhotoImage(Image.open('space_amoeba.gif').convert('RGBA').resize((size, size), Image.ANTIALIAS)) self.radius = (self._image.height()/2)+((self._image.width()**2)/(8 * self._image.height())) self._counter = 1 def update(self, model): result = Black_Hole.update(self,model) self._counter += 1 if len(result) > 0: self.set_dimension(self.get_dimension()[0] + len(result), self.get_dimension()[1] + len(result)) self._image = PhotoImage(Image.open('space_amoeba.gif').convert('RGBA').resize((self.get_dimension()[0], self.get_dimension()[1]), Image.ANTIALIAS)) self.radius = (self._image.height()/2)+((self._image.width()**2)/(8 * self._image.height())) self._counter = 1 if self._counter == Pulsator.counter: self.set_dimension(self.get_dimension()[0] - 1, self.get_dimension()[1] - 1) self._image = PhotoImage(Image.open('space_amoeba.gif').convert('RGBA').resize((self.get_dimension()[0], self.get_dimension()[1]), Image.ANTIALIAS)) self.radius = (self._image.height()/2)+((self._image.width()**2)/(8 * self._image.height())) self._counter = 1 if self.get_dimension() < (Pulsator.death,Pulsator.death): result.add(self) return result
def pil_image_viewer(): from PIL.ImageTk import PhotoImage imgdir = 'images' imgfile = 'florida-2009-1.jpg' if len(sys.argv) > 1: imgfile = sys.argv[1] imgpath = os.path.join(imgdir, imgfile) win = Tk() win.title(imgfile) imgobj = PhotoImage(file=imgpath) Label(win, image=imgobj).pack() win.mainloop() print(imgobj.width(), imgobj.height())
class Special(Simulton): def __init__(self,x,y): self._image = PhotoImage(Image.open('bigbang.gif').convert('RGBA').resize((20, 20), Image.ANTIALIAS)) Simulton.__init__(self,x,y,self._image.width(),self._image.height()) self._center = (int(x),int(y)) self._explosion = 500 def update(self, model): self._explosion = model.world()[1]/2 all_swallowed = True if self.get_dimension() >= model.world(): model.big_bang = None elif self.get_dimension() >= (self._explosion,self._explosion): total = model.world() for item in model.items: item.set_location(random.uniform(1,total[0] - 1),random.uniform(1,total[1] - 1)) self.set_dimension(total[0], total[1]) else: for item in model.items: location = item.get_location() location = (int(location[0]),int(location[1])) if location != self._center: all_swallowed = False if location[0] < self._center[0]: new_x = location[0] + 1 elif location[0] > self._center[0]: new_x = location[0] - 1 else: new_x = location[0] if location[1] < self._center[1]: new_y = location[1] + 1 elif location[1] > self._center[1]: new_y = location[1] - 1 else: new_y = location[1] item.set_location(new_x,new_y) else: self.change_dimension(1, 1) self._image = PhotoImage(Image.open('bigbang.gif').convert('RGBA').resize((self.get_dimension()[0], self.get_dimension()[1]), Image.ANTIALIAS)) if all_swallowed: self.change_dimension(10, 10) self._image = PhotoImage(Image.open('bigbang.gif').convert('RGBA').resize((self.get_dimension()[0], self.get_dimension()[1]), Image.ANTIALIAS)) def display(self,canvas): canvas.create_image(*self.get_location(),image=self._image)
class Ball(Prey): radius = 5 def __init__(self,x,y): self._image = PhotoImage(file='asteroid.gif') Prey.__init__(self,x,y,self._image.width(),self._image.height(),random.random()*math.pi*2,5) def update(self,model): self.move() return set() def display(self,canvas): canvas.create_image(*self.get_location(),image=self._image)
class Floater(Prey): def __init__(self,x,y): self._image = PhotoImage(file='ufo.gif') Prey.__init__(self,x,y,self._image.width(),self._image.height(),0,5) self.randomize_angle() def update(self,model): if random() <= .3: new_speed = min(7,max(3,self.get_speed() + random()-.5)) self.set_velocity(new_speed, self.get_angle()+random()-.5) self.move() def display(self,the_canvas): the_canvas.create_image(self._x,self._y,image=self._image)
class Floater(Prey): def __init__(self,x,y): self._image = PhotoImage(file='enterprise.gif') Prey.__init__(self,x,y,self._image.width(),self._image.height(),random.random()*math.pi*2,5) def update(self,model): if random.randint(1,10) <= 3: speed_difference = random.uniform(-0.5, 0.5) if self.get_speed() + speed_difference >= 3 and self.get_speed() + speed_difference <= 7: self.set_speed(self.get_speed() + speed_difference) self.set_angle(self.get_angle() + random.uniform(-0.5, 0.5)) self.move() return set() def display(self,canvas): canvas.create_image(*self.get_location(),image=self._image)
def drawImage(self, imgpil, forcesize=()): imgtk = PhotoImage(image=imgpil) scrwide, scrhigh = forcesize or self.maxsize() imgwide = imgtk.width() imghigh = imgtk.height() fullsize = (0, 0, imgwide, imghigh) viewwide = min(imgwide, scrwide) viewhigh = min(imghigh, scrhigh) canvas = self.canvas canvas.delete('all') canvas.config(height=viewhigh, width=viewwide) canvas.config(scrollregion=fullsize) canvas.create_image(0, 0, anchor=NW, image=imgtk) if imgwide <= scrwide and imghigh <= scrhigh: self.state('normal') elif sys.platform[:3] == 'win': self.state('zoomed') self.saveimage = imgpil self.savephoto =imgtk trace((scrwide, scrhigh), imgpil.size)
def drawImage(self, imgpil, forcesize=()): imgtk = PhotoImage(image=imgpil) # not file=imgpath scrwide, scrhigh = forcesize or self.maxsize() # wm screen size x,y imgwide = imgtk.width() # size in pixels imghigh = imgtk.height() # same as imgpil.size fullsize = (0, 0, imgwide, imghigh) # scrollable viewwide = min(imgwide, scrwide) # viewable viewhigh = min(imghigh, scrhigh) canvas = self.canvas canvas.delete('all') # clear prior photo canvas.config(height=viewhigh, width=viewwide) # viewable window size canvas.config(scrollregion=fullsize) # scrollable area size canvas.create_image(0, 0, image=imgtk, anchor=NW) if imgwide <= scrwide and imghigh <= scrhigh: # too big for display? self.state('normal') # no: win size per img elif sys.platform[:3] == 'win': # do windows fullscreen self.state('zoomed') # others use geometry() self.saveimage = imgpil self.savephoto = imgtk # keep reference on me trace((scrwide, scrhigh), imgpil.size)
class Hunter(Pulsator,Mobile_Simulton): sightDistance = 200 death = 10 def __init__(self,x,y,size = 20): Pulsator.__init__(self,x,y) Mobile_Simulton.__init__(self, x, y, self.radius, self.radius, random.random()*math.pi*2,5) self.set_dimension(size, size) self._image = PhotoImage(Image.open('deathstar.gif').convert('RGBA').resize((size, size), Image.ANTIALIAS)) self.radius = (self._image.height()/2)+((self._image.width()**2)/(8 * self._image.height())) def update(self, model): result = set() all_prey = model.find(lambda item:isinstance(item, Prey)) for item in all_prey: if self.contains(item): result.add(item) self._counter += 1 closest = self.sightDistance existing = all_prey - result for item in existing: if self.distance(item.get_location()) < closest: closest = self.distance(item.get_location()) self.set_angle(math.atan2(item.get_location()[1] - self.get_location()[1], item.get_location()[0] - self.get_location()[0])) if len(result) > 0: self.set_dimension(self.get_dimension()[0] + len(result), self.get_dimension()[1] + len(result)) self._image = PhotoImage(Image.open('deathstar.gif').convert('RGBA').resize((self.get_dimension()[0], self.get_dimension()[1]), Image.ANTIALIAS)) self.radius = (self._image.height()/2)+((self._image.width()**2)/(8 * self._image.height())) self._counter = 1 if self._counter == 30: self.radius -= 1 self.set_dimension(self.get_dimension()[0] - 1, self.get_dimension()[1] - 1) self._image = PhotoImage(Image.open('deathstar.gif').convert('RGBA').resize((self.get_dimension()[0], self.get_dimension()[1]), Image.ANTIALIAS)) self.radius = (self._image.height()/2)+((self._image.width()**2)/(8 * self._image.height())) self._counter = 1 self.move() if self.get_dimension() < (Hunter.death,Hunter.death): result.add(self) return result
import os, sys from tkinter import * from PIL.ImageTk import PhotoImage imgdir = '' imgfile = 'p1.jpg' # does gif, jpg, png, tiff, etc. if len(sys.argv) > 1: imgfile = sys.argv[1] imgpath = os.path.join(imgdir, imgfile) win = Tk() win.title(imgfile) imgobj = PhotoImage(file=imgpath) # now JPEGs work! Label(win, image=imgobj).pack() win.mainloop() print(imgobj.width(), imgobj.height())
""" show one image with PIL photo replacement object handles many more image types; install PIL first: placed in Lib\site-packages """ import os, sys from tkinter import * from PIL.ImageTk import PhotoImage # <== use PIL replacement class # rest of code unchanged imgdir = 'images' imgfile = 'florida-2009-1.jpg' # does gif, jpg, png, tiff, etc. if len(sys.argv) > 1: imgfile = sys.argv[1] imgpath = os.path.join(imgdir, imgfile) win = Tk() win.title(imgfile) imgobj = PhotoImage(file=imgpath) # now JPEGs work! Label(win, image=imgobj).pack() win.mainloop() print(imgobj.width(), imgobj.height()) # show size in pixels on exit
class UI: box_colors = {'fill': 'red', 'outline': 'red'} line_color = 'red' corner_radius = 2 def __init__(self, root): # toolbar stuff # https://www.youtube.com/watch?v=AYOs78NjYfc # set up window self.root = root self.root.geometry('650x400') # self.root.resizable(width=False, height=False) self.root.title('BrilliantImagery') self.root.iconbitmap(resource_path() / 'brilliantimagery_ui' / 'logo.ico') self.sequence = None self.canvas = None self.image = None self.point1 = () self.point2 = () self.last_points = ((), ()) self.files_last_parsed = None self._make_menu_bar() # set up tabs self.tab_control = ttk.Notebook(self.root) self._make_ramp_stabilize_tab() self._make_renderer_tab() def _make_menu_bar(self): def quite_app(): self.root.quit() self.menu = Menu(self.root) # ------ File Menu ------ file_menu = Menu(self.menu, tearoff=0) file_menu.add_command(label='Open Project', accelerator='Ctrl+O', command=self._open_project) file_menu.add_command(label='Save Project', accelerator='Ctrl+S', command=self._save_project) file_menu.add_separator() file_menu.add_command(label='Exit', command=quite_app) self.menu.add_cascade(label='File', menu=file_menu) # --------- Help Menu -------- help_menu = Menu(self.menu, tearoff=0) help_menu.add_command(label='About', command=lambda: messagebox.showinfo( 'About', f"BrilliantImagery UI\n\n" f"Version: " f"{brilliantimagery.__version__}" f"\nGo to brilliantimagery.org " f"for more info.")) self.menu.add_cascade(label='Help', menu=help_menu) self.root.config(menu=self.menu) def _make_renderer_tab(self): tab_renderer = ttk.Frame(self.tab_control) self.tab_control.add(tab_renderer, text='Renderer') self.tab_control.pack(expand=1, fill='both') interface_frame = Frame(tab_renderer) interface_frame.pack(side=TOP, anchor=W) Label(interface_frame, text='Image Path:').grid(row=0, column=0, padx=10, pady=10) file_entry = Entry(interface_frame, width=70) file_entry.grid(row=0, column=1) folder_button = Button(interface_frame, text='File', command=lambda: self._open_image(file_entry)) folder_button.grid(row=0, column=2, padx=10) image_frame = Frame(tab_renderer) image_frame.pack(expand=1, fill='both') self.renderer_canvas = Canvas(image_frame, width=500, height=350, scrollregion=(0, 0, 500, 350)) horizontal_scroll_bar = Scrollbar(image_frame, orient=HORIZONTAL) vertical_scroll_bar = Scrollbar(image_frame, orient=VERTICAL) horizontal_scroll_bar.pack(side=BOTTOM, fill=X) vertical_scroll_bar.pack(side=RIGHT, fill=Y) horizontal_scroll_bar.config(command=self.renderer_canvas.xview) vertical_scroll_bar.config(command=self.renderer_canvas.yview) self.renderer_canvas.pack(side=LEFT, expand=True, fill=BOTH) self.renderer_canvas.config(xscrollcommand=horizontal_scroll_bar.set, yscrollcommand=vertical_scroll_bar.set) def _make_ramp_stabilize_tab(self): # set up tab tab_ramp_stabilize = ttk.Frame(self.tab_control) self.tab_control.add(tab_ramp_stabilize, text='Ramp & Stabilize') self.tab_control.pack(expand=1, fill='both') # self.tab_control.grid(row=0, column=0) # make image canvas self.canvas = Canvas(tab_ramp_stabilize, width=255, height=255) self.canvas.grid(row=0, column=0, columnspan=2, rowspan=4) self.canvas.bind('<Button-1>', self._process_canvas_click) # make function checkboxes procedures_frame = LabelFrame(tab_ramp_stabilize, text='Operations To Perform') procedures_frame.grid(row=0, column=2, padx=5, pady=5, sticky=NW) self.ramp = IntVar() self.ramp_checkbutton = Checkbutton(procedures_frame, text="Ramp Linear Properties", variable=self.ramp) self.ramp_checkbutton.grid(row=0, column=0, sticky=W) self.exposure = IntVar() self.exposure_checkbutton = Checkbutton(procedures_frame, text="Ramp Exposure", variable=self.exposure) self.exposure_checkbutton.grid(row=1, column=0, sticky=W) self.stabilize = IntVar() self.stabilize_checkbutton = Checkbutton(procedures_frame, text="Stabilize", variable=self.stabilize) self.stabilize_checkbutton.grid(row=2, column=0, sticky=W) # Reload and reuse reuse_frame = LabelFrame(tab_ramp_stabilize, text='Data Reuse') reuse_frame.grid(row=1, column=2, padx=5, pady=5, sticky=NW) self.reuse_misalignment = IntVar() self.reuse_mis_checkbutton = Checkbutton( reuse_frame, text='Use Previously Calculated Misalignments', variable=self.reuse_misalignment) self.reuse_mis_checkbutton.grid(row=0, column=0, sticky=NW) self.reuse_brightness = IntVar() self.reuse_bright_checkbutton = Checkbutton( reuse_frame, text='Use Previously Calculated Brightnesses', variable=self.reuse_brightness) self.reuse_bright_checkbutton.grid(row=1, column=0, sticky=NW) Button(reuse_frame, text='Reload Image', command=lambda: (self._load_sequence(self.folder_entry.get()))).grid(row=2, column=0, sticky=NW, padx=5, pady=5) # set up folder selector folder_selector_row = 4 folder_selector_column = 0 Label(tab_ramp_stabilize, text='Sequence Folder:').grid(row=folder_selector_row, column=folder_selector_column, padx=10) self.folder_entry = Entry(tab_ramp_stabilize, width=70) self.folder_entry.grid(row=folder_selector_row, column=folder_selector_column + 1, columnspan=2) self.folder_entry.bind( '<FocusOut>', lambda e: self._load_sequence(self.folder_entry.get())) folder_button = Button(tab_ramp_stabilize, text='Folder', command=self._open_sequence) folder_button.grid(row=folder_selector_row, column=folder_selector_column + 3, sticky=W, padx=10) process_button = Button( tab_ramp_stabilize, text='Process', command=lambda: self._process_sequence(message_finished.get())) process_button.grid(row=folder_selector_row + 1, column=0, sticky=W, padx=10, pady=10) message_finished = IntVar() Checkbutton(tab_ramp_stabilize, text="Show MessageBox when done.", variable=message_finished).grid(row=folder_selector_row + 1, column=1, sticky=W) def _process_sequence(self, show_finished): if not self._validate_selections(): return self._maybe_reset_misalignment_brightness() rectangle = (min(self.point1[0], self.point2[0]), min(self.point1[1], self.point2[1]), max(self.point1[0], self.point2[0]), max(self.point1[1], self.point2[1])) rectangle = [ rectangle[0] / self.image.width(), rectangle[1] / self.image.height(), rectangle[2] / self.image.width(), rectangle[3] / self.image.height() ] last_modified = files_last_updated(self.sequence.path) if last_modified > self.files_last_parsed: self.sequence.parse_sequence() self.files_last_parsed = time.time() if self.ramp.get( ) and not self.exposure.get() and not self.stabilize.get(): self.sequence.ramp_minus_exmpsure() elif not self.ramp.get() and self.exposure.get( ) and not self.stabilize.get(): self.sequence.ramp_exposure(rectangle) elif not self.ramp.get() and not self.exposure.get( ) and self.stabilize.get(): self.sequence.stabilize(rectangle) elif self.ramp.get() and self.exposure.get( ) and not self.stabilize.get(): self.sequence.ramp(rectangle) elif not self.ramp.get() and self.exposure.get( ) and self.stabilize.get(): self.sequence.ramp_exposure_and_stabilize(rectangle) elif self.ramp.get( ) and not self.exposure.get() and self.stabilize.get(): self.sequence.ramp_minus_exposure_and_stabilize(rectangle) elif self.ramp.get() and self.exposure.get() and self.stabilize.get(): self.sequence.ramp_and_stabilize(rectangle) self.sequence.save() if self.exposure.get(): self.reuse_bright_checkbutton.select() if self.stabilize.get(): self.reuse_mis_checkbutton.select() self.last_points = (self.point1, self.point2) if show_finished: messagebox.showinfo('Done', 'All done!') print('Done Processing!') def _maybe_reset_misalignment_brightness(self): folder = Path(self.folder_entry.get()) files = [ f.name for f in folder.iterdir() if (folder / f).is_file() and f.suffix.lower() == '.dng' ] if (self.point1, self.point2) != self.last_points: self.sequence.set_misalignments({f: None for f in files}) self.sequence.set_brightnesses({f: None for f in files}) else: if not self.reuse_misalignment.get(): self.sequence.set_misalignments({f: None for f in files}) if not self.reuse_brightness.get(): self.sequence.set_brightnesses({f: None for f in files}) def _open_sequence(self): folder = self._open_folder(self.folder_entry) if folder: self._load_sequence(folder) def _load_sequence(self, folder): if not Path(folder).is_dir(): return if not self.sequence or folder != self.sequence.path: self.sequence = Sequence(folder) self.files_last_parsed = time.time() image = self.sequence.get_reference_image(index_order='yxc') image = PIL.Image.fromarray(image.astype('uint8'), mode='RGB') size = (255, int(255 * image.width / image.height)) image.thumbnail(size, Image.ANTIALIAS) self.image = PhotoImage(image) self._draw_image() def _open_folder(self, entry): folder = filedialog.askdirectory(title='Select A Sequence Folder') if not folder: return self._set_text(entry, folder) return folder def _open_image(self, entry): file = self._open_file(entry) if not file: return dng = DNG(file) image_array = dng.get_image() * 255 shape = image_array.shape image_array = np.reshape(image_array, image_array.size, 'C') image_array = np.reshape(image_array, (shape[2], shape[1], shape[0]), 'F') image = PIL.Image.fromarray(image_array.astype('uint8'), mode='RGB') self.image_rendered = PhotoImage(image) self.renderer_canvas.create_image(self.image_rendered.width(), self.image_rendered.height(), image=self.image_rendered, anchor=SE) self.renderer_canvas.config(scrollregion=(0, 0, image.width, image.height)) def _open_file(self, entry): file = filedialog.askopenfilename(title='Select an Image to Render', filetypes=(('dng files', '*.dng'), ('all files', '*.*'))) if not file: return self._set_text(entry, file) return file def _set_text(self, entry, text): entry.delete(0, END) entry.insert(0, text) return def _process_canvas_click(self, click=None): if not self.image: return self._get_point(click) self._draw_image() if not self.point2: self.reuse_mis_checkbutton.deselect() self.reuse_bright_checkbutton.deselect() def _draw_image(self): if not self.image: return self.canvas.create_image(self.image.width(), self.image.height(), image=self.image, anchor=SE) if self.point1: self._draw_corner(self.point1) if self.point2: self._draw_corner(self.point2) self.canvas.create_rectangle(*self.point1, *self.point2, outline=UI.line_color) def _get_point(self, click): if not click: return if not self.point1: self.point1 = (click.x, click.y) elif not self.point2: self.point2 = (click.x, click.y) else: self.point1 = () self.point2 = () def _draw_corner(self, point): _point1 = (max(0, point[0] - UI.corner_radius), max(0, point[1] - UI.corner_radius)) _point2 = (min(self.image.width(), point[0] + UI.corner_radius), min(self.image.height(), point[1] + UI.corner_radius)) self.canvas.create_rectangle(*_point1, *_point2, **UI.box_colors) def _save_project(self): if self.sequence: misalignments = self.sequence.get_misalignments() brightnesses = self.sequence.get_brightnesses() else: misalignments = None brightnesses = None params = { 'point1': self.point1, 'point2': self.point2, 'ramp': self.ramp.get(), 'exposure': self.exposure.get(), 'stabilize': self.stabilize.get(), 'folder': self.folder_entry.get(), 'misalignments': misalignments, 'brightnesses': brightnesses, } params = json.dumps(params) file = filedialog.asksaveasfile(title='Save Project', mode='w', defaultextension='.bi', filetypes=[('BrilliantImagery Project', '.bi'), ("All Files", ".*")]) if not file: return file.write(params) file.close() def _open_project(self): file = filedialog.askopenfile(title='Open Project', mode='r', defaultextension='.bi', filetypes=[('BrilliantImagery Project', '.bi'), ("All Files", ".*")]) if not file: return params = file.read() file.close() params = json.loads(params) self.point1 = params.get('point1') self.point2 = params.get('point2') self.last_points = (self.point1, self.point2) if params.get('ramp'): self.ramp_checkbutton.select() else: self.ramp_checkbutton.deselect() if params.get('exposure'): self.exposure_checkbutton.select() else: self.exposure_checkbutton.deselect() if params.get('stabilize'): self.stabilize_checkbutton.select() else: self.stabilize_checkbutton.deselect() folder = params.get('folder') self._set_text(self.folder_entry, folder) self._load_sequence(folder) misalignments = params.get('misalignments') brightnesses = params.get('brightnesses') if misalignments: self.sequence.set_misalignments(misalignments) if list(misalignments.values())[0] != None: self.reuse_mis_checkbutton.select() if brightnesses: self.sequence.set_brightnesses(brightnesses) if list(brightnesses.values())[0] != None: self.reuse_bright_checkbutton.select() def _validate_selections(self): if self.point1 and self.point2: rectangle = True else: rectangle = False if not self.folder_entry.get(): messagebox.showerror('Oops!', 'You need to specify a Sequence Folder.') return False if rectangle and (self.exposure.get() or self.stabilize.get()): return True elif self.reuse_brightness.get() and self.exposure.get(): return True elif self.reuse_misalignment.get() and self.stabilize.get(): return True elif self.ramp.get() and not (self.exposure.get() or self.stabilize.get()): return True messagebox.showerror( 'Oops!', "You need to specify what to do (in the Operations to Perform box) " "and what information to use (either highlight a rectangle or select " "what info to reuse)") return False
def refreshWidget(self) : #print "refresh" self.card_win.pack_forget() import unicodedata #Card window self.card_win = PanedWindow(self.card_win.master, orient=VERTICAL) self.card_win.pack(side=TOP, expand=True, fill=BOTH, pady=2, padx=2) #Create the name zone name_zone=PanedWindow(self.card_win, orient=HORIZONTAL) name = StringVar() name.set(self.name) def modifName(*args) : try : assert('"' not in name.get()) name.get().encode('ascii') except Exception as e: print ("error on name") name.set(self.name) return old = self.name in Card.blocked_creature self.name=name.get() if old or self.name in Card.blocked_creature : self.refreshWidget() name.trace("w", modifName) name_wid=Entry(name_zone, width=30,textvariable=name) name_wid.pack() name_zone.add(name_wid) #Create the cost ad star stringvar #print int(floor(self.getCost())) self.cost=StringVar() self.stars=StringVar() cost_wid=Label(None, textvariable=self.cost, background='red',width=5, anchor=W) star_wid=Label(None, textvariable=self.stars, background='blue', anchor=E) self.cost.set(str(int(floor(self.getCost())))) self.stars.set("*"*self.getStars()) #Add them in name zone name_zone.add(cost_wid) name_zone.add(star_wid) #Create an Image Zone image_zone=Button(self.card_win, command=self.choosePhoto) if hasattr(self,"photofile") and self.photofile : print ("Image: ",self.photofile) try : pilImage=Image.open(self.photofile) img=PhotoImage(pilImage,master=image_zone) except : decomp=self.photofile.split('/') for i in range(1,6) : try : fname="/".join(decomp[-i:]) print ("try to open",fname) pilImage = Image.open(fname) img=PhotoImage(pilImage,master=image_zone) self.photofile=fname break except : self.photofile=None if self.photofile : w, h = img.width(), img.height() print('wh',w,h) if h>400 : print("reduction") img=PhotoImage(pilImage.resize((w//2,h//2), Image.ANTIALIAS),master=image_zone) image_zone=Button(self.card_win,image=img, command=self.choosePhoto) image_zone.image=img #image_zone.configure(image=image_zone.image,width=50,height=50,compound=RIGHT) #image_zone.pack() #print "IMAGE CHANGED" else : from os import path fname=self.name.replace(" ","_") if path.isfile("Cards/"+fname+".png") : image_zone.config(text='image can be taken from\n'+"Cards/"+fname+".png",background='white',anchor=CENTER) else : image_zone.config(text='clic to choose image',background='white',anchor=CENTER) #image_zone.pack() # POWER ZONE power_zone=PanedWindow(self.card_win, orient=VERTICAL) #fenetre=self.card_win.master def removePowerCreator(px) : def removePower(*args) : #print 'avant',list_pow self.bonus.remove(px) #print 'apres',list_pow #self.card_win.pack_forget() self.refreshWidget() return removePower for p in self.bonus : powline = PanedWindow(self.card_win, orient=HORIZONTAL) pow_wid=p.initWidget(powline) powline.add(pow_wid) removepow=Button(powline, text="X", command=removePowerCreator(p), anchor=E) removepow.pack() powline.add(removepow) power_zone.add(powline) def addPower(*args) : if addBonus.get()!= "add bonus": name=addBonus.get() else: name=add_cost_alteration.get() print ("added :",name) import CardPowers self.bonus+=[eval('CardPowers.'+name+'()')] self.bonus[-1].parent=self.bonus self.bonus[-1].card=self #self.card_win.pack_forget() self.refreshWidget() #Add bonus Option menu addBonus = StringVar(power_zone) addBonus.set("add bonus") # default value if not self.pv: addBonus_wid = Spell.getSpellMenu(power_zone, addBonus) else: addBonus_wid = getBonusMenu(power_zone, addBonus) addBonus.trace('w', addPower) if self.pv>0 or len(self.bonus)==0 or all([b.is_cost_alterator for b in self.bonus]): addBonus_wid.pack() #Add this to power zone power_zone.add(addBonus_wid) #Create save zone save_zone = PanedWindow(self.card_win, orient=HORIZONTAL) if self.monster_type != "all" and not(self.name in Card.blocked_creature) : save_wid = Button(save_zone, text="Save", command=self.postAndSave) elif self.monster_type != "all" : save_wid = Button(save_zone, text="creature in campaign", command=None) else: save_wid = Button(save_zone, text="nead type", command=None) save_wid.pack() #Create the open button save_zone.pack() if Card.monster_list.keys(): self.opening = StringVar(save_zone) self.opening.set("Open") choice = [na for na in Card.monster_list.keys() if na not in Card.blocked_creature] choice.sort() #print all_monsters.keys() open_wid = OptionMenu(save_zone, self.opening,*choice) self.opening.trace('w', self.Open) open_wid.pack() save_zone.add(open_wid) if Card.monster_list.keys(): self.delete = StringVar(save_zone) self.delete.set("Delete") choice = [na for na in Card.monster_list.keys() if na not in Card.blocked_creature] choice.sort() delete_wid = OptionMenu(save_zone, self.delete,*choice) self.delete.trace('w', self.clicDelete) delete_wid.pack() save_zone.add(delete_wid) #Create the type button self.category = StringVar(save_zone) self.category.set(self.monster_type) choice = [file2name(t,"_monsters.sav") for t in glob.glob("CardFiles/*_monsters.sav")] if "recup" in choice: choice.remove("recup") #print all_monsters.keys() category_wid = OptionMenu(save_zone, self.category,*choice) self.category.trace('w', self.setFile) category_wid.pack() #Add it to save zone save_zone.add(save_wid) save_zone.add(category_wid) #Create a new Strength zone for att and pv strength_zone=PanedWindow(self.card_win, orient=HORIZONTAL) att=StringVar() att.set(str(self.att)) pv=StringVar() ; pv.set(str(self.pv)) def modifiedAttPv(*args) : print ("modifiedAttPv") self.pv=int(pv.get()) if self.pv<1 and self.is_spell==False : if len(self.bonus)==0 : self.is_spell=True self.refreshWidget() else : self.pv=1 self.refreshWidget() if self.pv>0 and self.is_spell==True : if len(self.bonus)==0 : self.is_spell=False self.refreshWidget() else : self.pv=0 self.refreshWidget() self.att=int(att.get()) self.getCost() att_wid = Spinbox(strength_zone, from_=0, to=1000,textvariable=att,command=modifiedAttPv) att_wid.pack() strength_zone.add(att_wid) strength_zone.add(Label(strength_zone, text=' ', background='white', anchor=CENTER)) pv_wid = Spinbox(strength_zone, from_=0, to=1000,textvariable=pv,command=modifiedAttPv) pv_wid.pack() strength_zone.add(pv_wid) #Put it all in window self.card_win.add(name_zone) self.card_win.add(image_zone) self.card_win.add(power_zone) self.card_win.add(strength_zone) self.card_win.add(save_zone) self.card_win.pack()
GIF-файлы поддерживаются стандартными средствами tkinter, но JPEG-файлы будут пропускаться при отсутствии пакета PIL """ import os, sys from tkinter import * from PIL.ImageTk import PhotoImage # <== требуется для JPEG и др. форматов imgdir = 'images' if len(sys.argv) > 1: imgdir = sys.argv[1] imgfiles = os.listdir(imgdir) # не включает полный путь к каталогу main = Tk() main.title('Viewer') quit = Button(main, text='Quit all', command=main.quit, font=('courier', 25)) quit.pack() savephotos = [] for imgfile in imgfiles: imgpath = os.path.join(imgdir, imgfile) win = Toplevel() win.title(imgfile) try: imgobj = PhotoImage(file=imgpath) Label(win, image=imgobj).pack() print(imgpath, imgobj.width(), imgobj.height()) # размер в пикселях savephotos.append(imgobj) # сохранить ссылку except: errmsg = 'skipping % s\n % s' % (imgfile, sys.exc_info()[1]) Label(win, text=errmsg).pack()
"""отображает изображение с помощью стандартного объекта PhotoImage из биб- # лиотеки tkinter; данная реализация может работать с GIF-файлами, но не может # обрабатывать изображения в формате JPEG; использует файл с изображением, имя # которого указано в командной строке, или файл по умолчанию; используйте Canvas # вместо Label, чтобы обеспечить возможность прокрутки, и т.д. # """ import os, sys from tkinter import * from PIL.ImageTk import PhotoImage dir = './images/' photo = 'Lighthouse.jpg' if len(sys.argv) > 1: photo = sys.argv[1] path = os.path.join(dir, photo) win = Tk() win.title(photo) photo_obj = PhotoImage(file=dir + photo) Label(win, image=photo_obj).pack() print(photo_obj.width(), photo_obj.height()) win.mainloop()
import os, sys from tkinter import * from PIL.ImageTk import PhotoImage # <== required for JPEGs and others imgdir = 'images' if len(sys.argv) > 1: imgdir = sys.argv[1] imgfiles = os.listdir(imgdir) # does not include directory prefix main = Tk() main.title('Viewer') quit = Button(main, text='Quit all', command=main.quit, font=('courier', 25)) quit.pack() savephotos = [] for imgfile in imgfiles: imgpath = os.path.join(imgdir, imgfile) win = Toplevel() win.title(imgfile) try: imgobj = PhotoImage(file=imgpath) Label(win, image=imgobj).pack() print(imgpath, imgobj.width(), imgobj.height()) # size in pixels savephotos.append(imgobj) # keep a reference except: errmsg = 'skipping %s\n%s' % (imgfile, sys.exc_info()[1]) Label(win, text=errmsg).pack() main.mainloop()
""" отображает изображение с помощью альтернативного объекта из пакета PIL поддерживает множество форматов изображений; предварительно установите пакет PIL: поместите его в каталог Lib\site-packages """ import os, sys from tkinter import * from PIL.ImageTk import PhotoImage imgdir = 'images' imgfile = 'spb_backyard.jpg' # поддерживает gif, jpg, png, tiff, и др. if len(sys.argv) > 1: imgfile = sys.argv[1] imgpath = os.path.join(imgdir, imgfile) win = Tk() win.title(imgfile) imgobj = PhotoImage(file=imgpath) # теперь поддерживает и JPEG! Label(win, image=imgobj).pack() win.mainloop() print(imgobj.width(), imgobj.height()) # показать размер в пикселях при выходе
class Application(Frame): """Container class, encapsulates app""" # this class inherits from Tkinter.parent def __init__(self, path, master=None): """Constructor""" # call parent class constructor Frame.__init__(self, master) self.path = path self.image_filenames = find_image_files(path) # necessary to make the application actually appear on the screen self.grid(sticky=N + S + E + W) # PIL image, for loading from file and for resizing self.image_pil = None # Tk photoimage, for display self.image_tk = None # list of coords (2-element lists) of current selection's pts self.points_orig = [] # points_canvas is 'points_orig', in canvas coordinates self.points_canvas = [] # x- and y-coords of displayed image in canvas coordinate frame self.x_offset = -1 self.y_offset = -1 # font in listbox text self.font = Font(family='Helvetica', size=10, weight='normal') # crosshair line size , as fraction of # min(displayed-imagewidth, displayed-image-height) self.crosshair_fraction = 0.05 # color for drawing first crosshair - the origin self.crosshair1_color = 'red' # color for drawing second crosshair - (together with the first # crosshair, these two points define a coordinate frame) - self.crosshair2_color = 'green' # color for drawing third and on crosshairs - all points other # than the first and second, have this color self.crosshair3_color = 'cyan' # the width, in pixels, of crosshairs self.crosshair_thickness = 2 # length of crosshair (updated upon display) self.crosshair_radius = -1 # the scale of currently displayed image (updated upon display) self.image_scaling = 1.0 # create all widges and set their initial conditions self.create_widgets() def create_widgets(self): """Set up all application graphics""" # get the top level winddow top = self.winfo_toplevel() # set the title of the top level window top.title('Image Point Tagging Tool') # make row 0 of the top level window's grid stretchable top.rowconfigure(0, weight=1) # make column 0 of the top level window's grid stretchable top.columnconfigure(0, weight=1) # bind keys for entire app top.bind_all('<Up>', self.select_prev) top.bind_all('<Down>', self.select_next) # make row 0 of Application's widget's grid stretchable self.rowconfigure(0, weight=1) # make column 0 of Application's widget's grid stretchable self.columnconfigure(0, weight=1) self.canvas = Canvas(self, bg='gray') self.canvas.grid(row=0, column=0, rowspan=2, sticky=N + S + E + W) self.canvas.rowconfigure(0, weight=1) self.canvas.columnconfigure(0, weight=1) # bind resize events (need -4 here bec. event gives 4+(real_size)) self.canvas.bind( '<Configure>', lambda e, s=self: s.on_resize_canvas(e.width - 2, e.height - 2)) # bind canvas mouse clicks self.canvas.bind('<Button-1>', self.on_click_button1) self.canvas.bind('<Button-3>', self.on_click_button3) # create scrollbars self.scrollbar_x = Scrollbar(self, orient=HORIZONTAL, width=10) self.scrollbar_y = Scrollbar(self, orient=VERTICAL, width=10) self.scrollbar_x.grid(row=1, column=1, columnspan=2, sticky=E + W) self.scrollbar_y.grid(row=0, column=3, sticky=N + S) # create lb for showing labeled/not-labeled images self.listbox_marks = Listbox(self, width=1, takefocus=0, exportselection=0, font=self.font) self.listbox_marks.grid(row=0, column=1, sticky=N + S + E + W) # create lb for showing image filenames self.lisbox_filenames = Listbox(self, width=30, selectmode=SINGLE, xscrollcommand=self.scrollbar_x.set, yscrollcommand=self.scrollbar_y.set, exportselection=0, font=self.font) self.lisbox_filenames.grid(row=0, column=2, sticky=N + S + E + W) # bind scrollbar movement self.scrollbar_x['command'] = self.lisbox_filenames.xview self.scrollbar_y['command'] = self.on_scrollbar_y # bind left mouse click selection self.lisbox_filenames.bind( '<Button-1>', lambda e, s=self: s.select(self.lisbox_filenames.nearest(e.y))) self.listbox_marks.bind( '<Button-1>', lambda e, s=self: s.select(self.lisbox_filenames.nearest(e.y))) # bind wheel scroll self.lisbox_filenames.bind( '<Button-4>', lambda e, s=self: on_mousewheel(self.listbox_marks, 4)) self.lisbox_filenames.bind( '<Button-5>', lambda e, s=self: on_mousewheel(self.listbox_marks, 5)) self.listbox_marks.bind( '<Button-4>', lambda e, s=self: on_mousewheel(self.lisbox_filenames, 4)) self.listbox_marks.bind( '<Button-5>', lambda e, s=self: on_mousewheel(self.lisbox_filenames, 5)) # skip is # of chars to skip in path string so that only the # part of the path that was not supplied is displayed skip = len(self.path) if self.path[skip - 1] != '/': skip += 1 # insert image filenames plus marks into lists and # select first image that does not have pts file i = 0 index_of_image_with_no_pts_file = -1 for image_filename in self.image_filenames: self.lisbox_filenames.insert(END, image_filename[skip:]) if self.has_pts_file(i): self.listbox_marks.insert(END, '+') else: self.listbox_marks.insert(END, '') if index_of_image_with_no_pts_file < 0: index_of_image_with_no_pts_file = i i += 1 if index_of_image_with_no_pts_file < 0: self.select(0) else: self.select(index_of_image_with_no_pts_file) def on_scrollbar_y(self, *args): """Vertical scrollbar motion callback""" apply(self.lisbox_filenames.yview, args) apply(self.listbox_marks.yview, args) def on_click_button1(self, event): """Button 1 click callback: adds a crosshair at click location""" if self.coord_in_img(event.x, event.y): point = [(event.x - self.x_offset) / self.image_scaling, (event.y - self.y_offset) / self.image_scaling] point_scaled = [float(event.x), float(event.y)] self.points_orig.append(point) self.points_canvas.append(point_scaled) if len(self.points_orig) == 1: self.mark_labeled() self.on_resize_canvas(int(self.canvas['width']), int(self.canvas['height'])) self.save_points() def on_click_button3(self, event): """Button 3 click callback: deletes landmark near click location""" if not self.coord_in_img(event.x, event.y): return i = self.find_point_near_crosshair(event.x, event.y) if i >= 0: del self.points_orig[i] del self.points_canvas[i] if len(self.points_orig) == 0: self.mark_unlabeled() self.on_resize_canvas(int(self.canvas['width']), int(self.canvas['height'])) self.save_points() def select(self, i): """Select the i'th image to work with - make current selection = i""" # uncomment the following line if you are only dealing with # faces that have three points labeled on them and you want to # automatically reorder a previously tagged database so that # the person's right eye is the first point, left eye is # second point and mouth is third point self.sort_points() self.lisbox_filenames.selection_clear(0, END) self.listbox_marks.selection_clear(0, END) self.lisbox_filenames.selection_set(i) self.listbox_marks.selection_set(i) self.lisbox_filenames.see(i) self.listbox_marks.see(i) self.image_pil = PIL.Image.open(self.get_image_filename()) self.points_orig = self.read_pts_file() self.on_resize_canvas(int(self.canvas['width']), int(self.canvas['height'])) def select_prev(self, *args): #pylint: disable=unused-argument """Select entry that comes before current selection""" i = self.get_selected_index() if i > 0: self.select(i - 1) def select_next(self, *args): #pylint: disable=unused-argument """Select entry that comes after current selection""" i = self.get_selected_index() if i < len(self.image_filenames) - 1: self.select(i + 1) def on_resize_canvas(self, width, height): """Called when canvas is resized""" if width <= 0 or height <= 0: return # maximize image width or height depending on aspect ratios image_width = self.image_pil.size[0] image_height = self.image_pil.size[1] image_aspect_ratio = float(image_width) / float(image_height) self.canvas['width'] = width self.canvas['height'] = height canvas_width = int(self.canvas['width']) canvas_height = int(self.canvas['height']) canvas_aspect_ratio = float(canvas_width) / float(canvas_height) if image_aspect_ratio < canvas_aspect_ratio: new_image_width = int(image_aspect_ratio * float(canvas_height)) new_image_height = canvas_height else: new_image_width = canvas_width new_image_height = int(float(canvas_width) / image_aspect_ratio) self.image_tk = PhotoImage( self.image_pil.resize((new_image_width, new_image_height), PIL.Image.BILINEAR)) self.x_offset = 0.5 * (float(canvas_width) - float(new_image_width)) self.y_offset = 0.5 * (float(canvas_height) - float(new_image_height)) self.crosshair_radius = 0.5 * self.crosshair_fraction * float( min(new_image_width, new_image_height)) self.canvas.delete('image') self.canvas.create_image(self.x_offset, self.y_offset, anchor=NW, image=self.image_tk, tags='image') width_scale = float(new_image_width) / float(image_width) height_scale = float(new_image_height) / float(image_height) self.image_scaling = 0.5 * (width_scale + height_scale) self.points_canvas = [[ x[0] * self.image_scaling + self.x_offset, x[1] * self.image_scaling + self.y_offset ] for x in self.points_orig] self.redraw_points() def redraw_points(self): """redraw points in current entry's .pts file""" self.canvas.delete('line') # draw first crosshair in color1 if len(self.points_canvas) > 0: point1 = self.points_canvas[0] self.draw_crosshair(point1[0], point1[1], self.crosshair1_color) # draw second crosshair in color2 if len(self.points_canvas) > 1: point2 = self.points_canvas[1] self.draw_crosshair(point2[0], point2[1], self.crosshair2_color) # draw third or higher crosshair in color3 if len(self.points_canvas) > 2: for point in self.points_canvas[2:]: self.draw_crosshair(point[0], point[1], self.crosshair3_color) def draw_crosshair(self, x_coord, y_coord, fill_color): """Draw a cross at (x_coord, y_coord) in the currently selected image""" start_x = x_coord - self.crosshair_radius start_y = y_coord - self.crosshair_radius end_x = x_coord + self.crosshair_radius end_y = y_coord + self.crosshair_radius min_x = self.x_offset min_y = self.y_offset max_x = self.x_offset + self.image_tk.width() - 1 max_y = self.y_offset + self.image_tk.height() - 1 if start_x < min_x: start_x = min_x if start_y < min_y: start_y = min_y if end_x > max_x: end_x = max_x if end_y > max_y: end_y = max_y self.canvas.create_line(x_coord, start_y, x_coord, end_y, width=self.crosshair_thickness, tags='line', fill=fill_color) self.canvas.create_line(start_x, y_coord, end_x, y_coord, width=self.crosshair_thickness, tags='line', fill=fill_color) def get_selected_index(self): """Returns index of current selection""" return int(self.lisbox_filenames.curselection()[0]) def coord_in_img(self, x_coord, y_coord): """Returns whether (x_coord, y_coord) is inside the shown image""" return (x_coord >= self.x_offset and y_coord >= self.y_offset and x_coord < self.x_offset + self.image_tk.width() and y_coord < self.y_offset + self.image_tk.height()) def find_point_near_crosshair(self, x_coord, y_coord): """Returns index of landmark point near (x_coord, y_coord), or -1""" i = 0 i_min = -1 min_dist = self.image_tk.width() + self.image_tk.height() for pair in self.points_canvas: x_dist = x_coord - pair[0] y_dist = y_coord - pair[1] dist = sqrt(x_dist * x_dist + y_dist * y_dist) if dist <= self.crosshair_radius and dist < min_dist: i_min = i i += 1 return i_min def save_points(self): """Save current points to pts file""" # remove whatever was there before if self.has_pts_file(): os.remove(self.get_pts_filename()) # save current result if len(self.points_orig) > 0: filehandle = open(self.get_pts_filename(), 'w') for pair in self.points_orig: message = str(pair[0]) + ', ' + str(pair[1]) + '\n' filehandle.write(message) filehandle.close() def sort_points(self): """ Reorder points, assuming face labeling, so that the first point is always the person's right eye, the second point is the person's left eye and the third point is the mouth. NB: this function only (destructively) works on self.points_orig """ if len(self.points_orig) != 3: return # step 1 sort the points according to y-value self.points_orig.sort(key=lambda pt: pt[1]) # step 2: from the top-most two points, call the leftmost one # the person's right eye and call the other the person's left eye if self.points_orig[0][0] > self.points_orig[1][0]: # swap first and second points' x-coordinate tmp = self.points_orig[0][0] self.points_orig[0][0] = self.points_orig[1][0] self.points_orig[1][0] = tmp # swap first and second points' y-coordinate tmp = self.points_orig[0][1] self.points_orig[0][1] = self.points_orig[1][1] self.points_orig[1][1] = tmp # order changed, so re-save self.save_points() def has_pts_file(self, i=None): """Returns whether (i'th) selection has a pts file with landmarks""" if i is None: i = self.get_selected_index() return os.path.exists(self.get_pts_filename(i)) def get_pts_filename(self, i=None): """Returns filename of selected (or i'th) .pts file""" if i is None: i = self.get_selected_index() image_filename = self.image_filenames[i] return os.path.splitext(image_filename)[0] + '.pts' def get_image_filename(self, i=None): """Returns filename of (i'th) selection's image""" if i is None: i = self.get_selected_index() return self.image_filenames[i] def read_pts_file(self, i=None): """Returns list of points (lists) in (i'th) selection's .pts file""" if i is None: i = self.get_selected_index() if self.has_pts_file(i): filehandle = open(self.get_pts_filename(i), 'r') lines = filehandle.readlines() filehandle.close() return [[float(pair[0]), float(pair[1])] for pair in [line.split(',') for line in lines]] else: return [] def mark_labeled(self, i=None): """Mark (i'th) selection as having a .pts file""" if i is None: i = self.get_selected_index() self.listbox_marks.insert(i, '+') self.listbox_marks.delete(i + 1) self.listbox_marks.selection_set(i) def mark_unlabeled(self, i=None): """Unmark (i'th) selection as having a .pts file""" if i is None: i = self.get_selected_index() self.listbox_marks.insert(i, '') self.listbox_marks.delete(i + 1) self.listbox_marks.selection_set(i)
""" import os, sys from tkinter import * from PIL.ImageTk import PhotoImage # <== required for JPEGs and others imgdir = 'images' if len(sys.argv) > 1: imgdir = sys.argv[1] imgfiles = os.listdir(imgdir) # does not include directory prefix main = Tk() main.title('Viewer') quit = Button(main, text='Quit all', command=main.quit, font=('courier', 25)) quit.pack() savephotos = [] for imgfile in imgfiles: imgpath = os.path.join(imgdir, imgfile) win = Toplevel() win.title(imgfile) try: imgobj = PhotoImage(file=imgpath) Label(win, image=imgobj).pack() print(imgpath, imgobj.width(), imgobj.height()) # size in pixels savephotos.append(imgobj) # keep a reference except: errmsg = 'skipping %s\n%s' % (imgfile, sys.exc_info()[1]) Label(win, text=errmsg).pack() main.mainloop()
#!/usr/local/bin/python #coding: utf-8 ''' Created on 2016年3月6日 @author: Calvin Wang ''' from learning.GUI.chapter2.imageButton import jpgdir from sys import argv from tkinter import * from PIL.ImageTk import PhotoImage filename = argv[1] if len(argv) > 1 else jpgdir # filename on cmdline? win = Tk() img = PhotoImage(file=filename) can = Canvas(win) can.pack(fill=BOTH) can.config(width=img.width(),height=img.height()) # set size to img's size can.create_image(2,2,image=img,anchor=NW) win.mainloop()
#!usr/local/bin/python #coding: utf-8 ''' Created on 2016年3月6日 @author: Calvin Wang ''' from tkinter import * from PIL.ImageTk import PhotoImage import sys,os imgdir = 'F:\Python\images' imgfile = '331018.jpg' if len(sys.argv) > 1: imgdir = sys.argv[1] imgpath = os.path.join(imgdir,imgfile) win = Tk() win.title(imgfile) imgobj = PhotoImage(file=imgpath) Label(win,image=imgobj).pack() print(imgobj.width(),imgobj.height()) win.mainloop()
class Application(Frame): def __init__(self, root): # Initial variables self.root = root self.rect = None self.start_x = None self.start_y = None self.current_x = None self.current_y = None self.image = None self.video = None self.job = None Frame.__init__(self, self.root, background='white') frame_left = Frame(self, padx=5, pady=5) frame_left.rowconfigure(1, pad=10) frame_left.grid(row=0, column=0, sticky=(N, W, E, S)) btn_open_img = Button(frame_left, text='Open Image', width=10, command=self.open_image) btn_open_img.grid(row=0, column=0) btn_open_video = Button(frame_left, text='Open Video', width=10, command=self.open_video) btn_open_video.grid(row=1, column=0) btn_clear = Button(frame_left, text='Clear', width=10, command=self.delete_rect) btn_clear.grid(row=2, column=0) btn_close = Button(frame_left, text='Close', width=10, command=self.quit) btn_close.grid(row=3, column=0) # Create and setting canvas self.canvas = Canvas(self, cursor='cross', highlightthickness=2, highlightbackground='#ccc') self.canvas.bind('<ButtonPress-1>', self.start_draw) self.canvas.bind('<B1-Motion>', self.drawing) self.canvas.bind("<ButtonRelease-1>", self.end_draw) self.canvas.grid(row=0, column=1) self.pack(fill=BOTH, expand=1) self.root.title('Drawing Rectangle') self.root.mainloop() def open_image(self): file_name = filedialog.askopenfilename( initialdir='/', title='Select file', filetypes=(('jpeg files', '*.jpg'), ('png files', '*.png'), ('tif files', '*.tif'))) if file_name: self.stop_video() self.image = PhotoImage(file=file_name) width, height = self.image.width(), self.image.height() self.canvas.config(width=width, height=height) self.canvas.create_image(0, 0, image=self.image, anchor=NW) def open_video(self): file_name = filedialog.askopenfilename( initialdir='/', title='Select file', filetypes=(('avi files', '*.avi'), ('mp4 files', '*.mp4'))) if file_name: self.stop_video() # Open video source self.video = VideoReader(file_name) width, height = self.video.width, self.video.height self.canvas.config(width=width, height=height) self.play_video() def play_video(self, delay=15): # Get a frame from the video source ret, frame = self.video.get_frame() if ret: self.image = PILPhotoImage(image=fromarray(frame)) self.canvas.create_image(0, 0, image=self.image, anchor=NW) if self.rect and self.start_x and self.start_y and self.current_x and self.current_y: # Delete rectangle of previous image self.delete_rect() # Create new rectangle for this image self.rect = self.canvas.create_rectangle(self.start_x, self.start_y, self.current_x, self.current_y, outline='red', width=2) # Drawing rectangle with top-left position and bottom-right position self.canvas.coords(self.rect, self.start_x, self.start_y, self.current_x, self.current_y) self.job = self.root.after(delay, self.play_video) def pause_video(self): if self.job is not None: self.root.after_cancel(self.job) self.job = None def stop_video(self): if self.job is not None: self.root.after_cancel(self.job) self.video.release() self.delete_rect() self.job = None def start_draw(self, event): self.pause_video() self.delete_rect() # Save start position of mouse self.start_x = self.canvas.canvasx(event.x) self.start_y = self.canvas.canvasy(event.y) self.current_x = self.canvas.canvasx(event.x) self.current_y = self.canvas.canvasy(event.y) # Create new rectangle if not exists if not self.rect: self.rect = self.canvas.create_rectangle(0, 0, 1, 1, outline='red', width=2) def drawing(self, event): # Get current position of mouse self.current_x = self.canvas.canvasx(event.x) self.current_y = self.canvas.canvasy(event.y) # Drawing rectangle with top-left position and bottom-right position self.canvas.coords(self.rect, self.start_x, self.start_y, self.current_x, self.current_y) def end_draw(self, event): if self.video: self.play_video() def delete_rect(self): if self.rect: self.canvas.delete(self.rect) self.rect = None
def images_size(filepath): main= Tk() imgobj = PhotoImage(file=filepath) size=(imgobj.width(), imgobj.height()) return size
def resize_to_wallpaper(self) -> None: self.delete(self.wallpaper_id) image = PhotoImage(self.wallpaper) self.redraw_canvas((image.width(), image.height())) self.draw_wallpaper(image)
class VkMusAppGUI(Frame): def __init__(self, parent=None, **options): Frame.__init__(self, parent, **options) self.vk = VkMusic() self.authResult = [] self.makeAuthWidgets() self.myAfter() self.userMusic = [[]] self.findedMusic = [[]] self.threadInWork = 0 self.inSearchPlayList = False self.lastEntryName = None self.extraParams = {'dir': os.path.curdir, 'mkDir': False, 'reverse': False} def myAfter(self, time=1000): self.win.after(time, self.makeWidgets) def makeWidgets(self): try: if self.authResult[0]: maxSize = (820, 500) fname = os.path.join(resFileName, 'bg3.jpg') self.master.title('Music') self.master.geometry('%dx%d' % maxSize) self.master.maxsize(*maxSize) self.master.iconbitmap(os.path.join(resFileName, 'icon2.ico')) self.master.protocol("WM_DELETE_WINDOW", self.delCache) canvas = self.win.canvas canvas.delete("all") self.bg_image = PhotoImage(file=fname) canvas.create_image(0, 0, image=self.bg_image, anchor='nw') userInfo = self.vk.getUserInfo() userName = userInfo['first_name'] + ' ' + userInfo['last_name'] userPhotoURL = self.vk.getUserPhoto() userImage = requests.get(userPhotoURL).content userImage = Image.open(BytesIO(userImage)) self.userImage = PhotoImage(userImage) imageX = (200 - self.userImage.width()) / 2 imageY = 70 userNameY = self.userImage.height() + imageY + 10 canvas.create_image(imageX, imageY, image=self.userImage, anchor='nw') canvas.create_text(imageX, userNameY, fill='white', text=userName, anchor='nw') playBtnFile = os.path.join(resFileName, 'play.png') self.playButtonImage = PhotoImage(file=playBtnFile) playButton = Button(canvas, image=self.playButtonImage, bg='#3c3c3c', command=self.playMusic) playButton.pack() canvas.create_window(50, 300, width=30, height=30, window=playButton) self.currentSongText = canvas.create_text(70, 300, fill='white', anchor='w', text='Текущая композиция') lFrame = Frame(canvas) lFrame.pack() canvas.create_window(400, 200, width=400, height=300, window=lFrame) sbar = Scrollbar(lFrame) listbox = Listbox(lFrame, selectmode='EXTENDED', exportselection=False) sbar.config(command=listbox.yview) # связать sbar и list listbox.config(yscrollcommand=sbar.set) # сдвиг одного = сдвиг другого listbox.bind('<<ListboxSelect>>', self.showLastSelectSong) sbar.pack(side=RIGHT, fill=Y) # первым добавлен – посл. обрезан listbox.pack(side=LEFT, expand=YES, fill=BOTH) # список обрезается первым self.list = listbox self.var = StringVar() self.radioVal = ('playlist', 'search') playlist = Radiobutton(canvas, #command=self.getPlaylist, bg='#3c3c3c', variable=self.var, value=self.radioVal[0]) search = Radiobutton(canvas, #command=self.getMusic, bg='#3c3c3c', variable=self.var, value=self.radioVal[1]) playlist.pack(), search.pack() canvas.create_window(660, 65, window=playlist) canvas.create_window(660, 105, window=search) canvas.create_text(720, 65, fill='white', text='Мой плейлист') canvas.create_text(700, 105, fill='white', text='Искать') canvas.create_text(692, 145, fill='white', text='Название песни') songNameEntry = Entry(canvas) songNameEntry.pack() canvas.create_window(710, 165, window=songNameEntry) self.songNameEntry = songNameEntry self.master.bind('<Return>', lambda event: self.showMuscicList()) canvas.create_text(705, 200, fill='white', text='Номера композиций') numEntry = Entry(canvas) numEntry.pack() canvas.create_window(710, 220, window=numEntry) numEntry.bind('<KeyPress>', self.selectMultipleItems) self.numEntry = numEntry resBtn = Button(canvas, text='Найти', command=self.showMuscicList) dwlBtn = Button(canvas, text='Скачать', command=self.downloadMusic) extraOptBtn = Button(canvas, text='Доп. параметры', command=self.showExtraOpts) resBtn.pack(), dwlBtn.pack(), extraOptBtn.pack() canvas.create_window(675, 260, width=60, window=resBtn) canvas.create_window(745, 260, width=60, window=dwlBtn) canvas.create_window(710, 300, height=35, width=130, window=extraOptBtn) progressbar = ttk.Progressbar (canvas, mode="determinate") progressbar.pack() canvas.create_window(400, 400, width=400, window=progressbar) self.progressbar = progressbar generalProgressbar = ttk.Progressbar (canvas, mode="determinate") generalProgressbar.pack() canvas.create_window(400, 450, width=400, window=generalProgressbar) self.generalProgressbar = generalProgressbar self.songNumInfo = canvas.create_text(200, 35, fill='white', anchor='w', text='') self.canvas = canvas ##### Show playlist at start ##### self.showPlayList() ################################## else: showerror('Ошибка', 'Авторизация не удалась!') del self.authResult[0] self.myAfter() except IndexError: self.myAfter() def makeAuthWidgets(self): self.win = AuthGUI(act=self.vk.authVk, result=self.authResult) def showExtraOpts(self): ExtraOptionsGUI(self, extraParams=self.extraParams) if self.extraParams['reverse']: self.list.select_set(0, END) if self.extraParams['mkDir']: self.makeDir() def delCache(self): if os.path.exists(cacheFileName): for fileName in os.listdir(cacheFileName): path = os.path.join(cacheFileName, fileName) os.remove(path) self.quit() def makeThread(self, func, args): th = threading.Thread(target=func, args=args) th.daemon = True th.start() def getPlaylist(self): self.makeThread(self.vk.getUserMusic, (self.userMusic,)) def getMusic(self): if self.songNameEntry.get(): name = self.songNameEntry.get() self.makeThread(self.vk.getMusic, (name, self.findedMusic)) self.lastEntryName = name else: showinfo('Ошибка!', 'Введите название песни!') def selectMultipleItems(self, event): def listIteration(somelist, func): for pos in somelist: try: if '-' in pos: first = pos[ : pos.find('-')] last = pos[pos.find('-')+1:] func(first, last) else: func(pos) except (TclError): pass def clearExtraSelections(selection, func): if hasattr(self, 'lastSelection'): extra = set(self.lastSelection) - set(selection) listIteration(extra, func) #self.list.select_clear self.lastSelection = selection if event.char.isprintable(): selection = self.numEntry.get() + event.char selection = selection.replace(' ', '').split(',') elif event.char == '\x08': selection = self.numEntry.get()[:-1].replace(' ', '').split(',') else: selection = self.numEntry.get().replace(' ', '').split(',') func = (self.list.select_set, self.list.select_clear) if self.extraParams['reverse'] else (self.list.select_clear, self.list.select_set) clearExtraSelections(selection, func[0]) listIteration(selection, func[1]) def showMuscicList(self): self.list.delete(0, 'end') self.threadInWork += 1 def prText(song, i): text = '{:>03}. {} - {} {}' duration = str(song['duration'] // 60) + ':' + str(song['duration'] % 60) return text.format(i, song['artist'], song['title'], duration) def startWork(musicL): self.songInfo = [] with threading.Lock(): i = 0 for song in musicL: if self.threadInWork > 1: self.threadInWork -= 1 return text = prText(song, i) try: self.list.insert(i, text) fname = song['artist'] + ' - ' + song['title'] + '.mp3' for pos in r'\/:><*?"|': fname = fname.replace(pos, '_') self.songInfo.append({'name': fname, 'url': song['url']}) except TclError: pass else: i+=1 self.canvas.itemconfig(self.songNumInfo, text=('Найдено %d композиций'%i)) self.threadInWork -= 1 if self.extraParams['reverse']: self.list.select_set(0, END) def threadShowMusic(musicL): if musicL[0]: self.makeThread(startWork, (musicL[0], )) else: self.after(500, threadShowMusic, musicL) if self.var.get() == self.radioVal[0]: if not self.userMusic[0] and not self.inSearchPlayList: self.inSearchPlayList = True self.getPlaylist() threadShowMusic(self.userMusic) self.canvas.itemconfig(self.songNumInfo, text='Загружаем плейлист...') elif self.var.get() == self.radioVal[1]: if self.lastEntryName != self.songNameEntry.get(): self.findedMusic[0] = [] self.getMusic() threadShowMusic(self.findedMusic) self.canvas.itemconfig(self.songNumInfo, text='Идет поиск...') else: showinfo('Ошибка', 'Выберите категорию!') self.threadInWork -= 1 def showPlayList(self): self.var.set('playlist') self.showMuscicList() def showLastSelectSong(self, event): try: num = self.list.curselection()[-1] song = self.songInfo[num]['name'] song = song if len(song) < 22 else (song[:18] + '...') self.canvas.itemconfig(self.currentSongText, text=song) except AttributeError: pass def playMusic(self): try: num = self.list.curselection()[-1] song = self.songInfo[num]['name'] file = os.path.join(cacheFileName, song) if not os.path.exists(cacheFileName): os.mkdir(cacheFileName) if not song in os.listdir(cacheFileName): with requests.get(self.songInfo[num]['url'], stream=True) as response: content = b'' for chunk in response.iter_content(1024*50): content +=chunk with open(file, "wb") as f: f.write(content) cmdline = '"%s"'%file os.system(cmdline) except Exception: showerror('Ошибка', 'Не удалось воспроизвести композицию!') def makeDir(self): newdir = os.path.join(self.extraParams['dir'], 'Music') if not os.path.exists(newdir): os.mkdir(newdir) self.extraParams['dir'] = newdir elif askyesno('Внимание!', 'Папка "Music" уже была создана ранее.\nИспользовать ее?'): self.extraParams['dir'] = newdir def downloadMusic(self): def threadDwnl(): curSelect = self.list.curselection() curSelectLen = len(curSelect) self.generalProgressbar['maximum'] = curSelectLen count = 0 totalText = 'Закачено: %03d из %03d' totalDownload = self.canvas.create_text(200, 430, fill='white', tag='total', anchor='w', text=totalText%(count, curSelectLen)) for num in curSelect: num = int(num) if not self.songInfo[num]['name'] in os.listdir(self.extraParams['dir']): file = os.path.join(self.extraParams['dir'], self.songInfo[num]['name']) text = self.songInfo[num]['name']+'...' self.canvas.create_text(200, 375, fill='white', tag='fileLabel', anchor='w', text=text) with requests.get(self.songInfo[num]['url'], stream=True) as response: content = b'' maxValue = response.headers['content-length'] self.progressbar['maximum'] = maxValue for chunk in response.iter_content(1024*50): self.progressbar['value']+=len(chunk) content +=chunk self.progressbar['value'] = 0 self.canvas.delete('fileLabel') with open(file, "wb") as file: file.write(content) count +=1 self.canvas.itemconfig(totalDownload, text=totalText%(count, curSelectLen)) self.generalProgressbar['value'] = count self.generalProgressbar['value'] = 0 self.canvas.delete('total') showinfo('Успех!', 'Загрузка завершена.') self.makeThread(threadDwnl, ())
gifdir = '/home/lhj/PycharmProjects/photo/gif/' from sys import argv from tkinter import * from PIL.ImageTk import PhotoImage filename = argv[1] if len(argv) > 1 else '2222.gif' win = Tk() img = PhotoImage(file=gifdir + filename) can = Canvas(win) can.pack(fill=BOTH) can.config(width=img.width(), height=img.height()) can.create_image(2, 2, image=img, anchor=NW) win.mainloop()
from tkinter import * # GIF works, but JPEG requires PIL imgfile1 = 'ora-pp3e.gif' imgfile2 = 'ora-lp4e.jpg' win = Tk() # make root first win.title('%s and %s' % (imgfile1, imgfile2)) imgobj1 = PhotoImage(file=imgfile1) # display standard photo on a Label Label(win, image=imgobj1).pack() print(imgobj1.width(), imgobj1.height()) # show size in pixels before destroyed from PIL.ImageTk import PhotoImage imgobj2 = PhotoImage(file=imgfile2) # display PIL photo on a Label Label(win, image=imgobj2).pack() print(imgobj2.width(), imgobj2.height()) # show size in pixels before destroyed win.mainloop()