# -*- coding: utf-8 -*- import os import tkinterdnd2 try: from Tkinter import * except ImportError: from tkinter import * root = tkinterdnd2.Tk() root.withdraw() root.title('TkinterDnD Canvas demo') root.grid_rowconfigure(1, weight=1, minsize=250) root.grid_columnconfigure(0, weight=1, minsize=300) Label(root, text='Drag and drop files here:').grid( row=0, column=0, padx=10, pady=5) buttonbox = Frame(root) buttonbox.grid(row=2, column=0, columnspan=2, pady=5) Button(buttonbox, text='Quit', command=root.quit).pack( side=LEFT, padx=5) file_data = ('R0lGODlhGAAYAKIAANnZ2TMzM////wAAAJmZmf///////////yH5BAEAAAAALAA' 'AAAAYABgAAAPACBi63IqgC4GiyxwogaAbKLrMgSKBoBoousyBogEACIGiyxwoKgGAECI' '4uiyCExMTOACBosuNpDoAGCI4uiyCIkREOACBosutSDoAgSI4usyCIjQAGCi63Iw0ACE' 'oOLrMgiI0ABgoutyMNAAhKDi6zIIiNAAYKLrcjDQAISg4usyCIjQAGCi63Iw0AIGiiqP' 'LIyhCA4CBosvNSAMQKKo4ujyCIjQAGCi63Iw0AIGiy81IAxCBpMu9GAMAgKPL3QgJADs' '=') folder_data = ('R0lGODlhGAAYAKECAAAAAPD/gP///////yH+EUNyZWF0ZWQgd2l0aCBHSU1QA' 'CH5BAEKAAIALAAAAAAYABgAAAJClI+pK+DvGINQKhCyztEavGmd5IQmYJXmhi7UC8frH' 'EL0Hdj4rO/n41v1giIgkWU8cpLK4dFJhAalvpj1is16toICADs=')
def browse_button(): # Allow user to select a directory and store it in global var # called folder_path global output_folder_path filename = filedialog.askdirectory() output_folder_path.set(filename) print(filename) def drop(event): entry_sv.set(event.data) root = tkinterdnd2.Tk(className='- JPG to PDF - ') root.geometry("500x300") root.wm_iconbitmap('img/logo.ico') var = tkinter.IntVar() a = tkinter.Label(root, text="PDF Name") a.place(x=10, y=50) a0 = tkinter.Label(root, text=" ↑ Drop JPG files over the field above shown ↑") a0.place(x=130, y=25) entry_sv = tkinter.StringVar() output_folder_path = tkinter.StringVar() lbl1 = tkinter.Label(master=root, textvariable=output_folder_path) lbl1.place(x=120, y=80) entry2_sv = tkinter.StringVar() entry = tkinter.Entry(root, textvar=entry_sv, width=50) entry.pack(fill=tkinter.X)
def test_version(self): root = tkinterdnd2.Tk() root.withdraw() self.assertEqual(root.TkdndVersion, '2.9.2')
def drag_and_drop_attempt(): """ The first attempt at creating a gui. :return None: """ class InitialState(BaseState): """ Initial state for the SimpleGUI. """ def _on_enter(self, gui): """ Construct the buttons upon entering the state. :return: """ print("In initial state.") '''Create drag and drop window''' gui.entry_sv = tk.StringVar() gui.drop_box_list = [] gui.drop_box_items = tk.Listbox(master=gui.root, listvariable=gui.drop_box_list) gui.drop_box_text = tk.StringVar() gui.drop_box_text.set("Drop images here") gui.entry = tk.Entry(gui.root, textvar=gui.drop_box_text, justify='center') gui.entry.config(font=("Courier", 44)) gui.entry.place(x=200, y=200, width=800, height=800) #gui.entry.pack() gui.entry.drop_target_register(DND_FILES) gui.entry.dnd_bind('<<Drop>>', self.drop(gui)) gui.update() def _on_exit(self, gui): """ Return the next state. :param gui: :return: """ gui.update() return WaitForDrop() def drop(self, gui): def _drop(event): files = root.tk.splitlist(event.data) gui.entry_sv.set(files) return _drop class WaitForDrop(BaseState): """ State for having buttons on. """ def _on_enter(self, gui): """ :param gui: :return: """ print("In wait for drop state.") def _state_main(self, gui): """ The main code for the ButtonsOn state. :param gui: :return: """ gui.entry.wait_variable(gui.entry_sv) '''Clean string''' files = literal_eval(gui.entry_sv.get()) '''Remove previous images''' if hasattr(gui, "panel"): gui.panel.destroy() '''Load each image''' for file_name in files: file_name = file_name.replace("{", "").replace("}", "") # image = tk.PhotoImage(file=file_name) if ".CR2" in file_name: '''Rawpy implementation''' file_image = rawpy.imread(file_name) file_image = file_image.postprocess() '''Rawkit implementation''' '''file_image = Raw(file_name) file_image = np.array(file_image.to_buffer())''' '''OpenCV implementation''' '''file_image = cv2.imread(file_name)''' else: file_image = Image.open(file_name) '''image = file_image.resize((500, 500), Image.ANTIALIAS) image = ImageTk.PhotoImage(image) gui.panel = tk.Label(gui.root, image=image) gui.panel.image = image gui.panel.pack()''' # panel.grid(row=2) image_data = np.array(file_image) image_data = cv2.cvtColor(image_data, cv2.COLOR_RGB2GRAY) '''print(image_data.shape) print(image_data) print(len(image_data)) print(len(image_data[0]))''' returned_image = Image.fromarray(image_data) '''cv2.imshow("Gray", image_data) cv2.waitKey() cv2.destroyWindow("Gray")''' '''enhanced_contrast = ImageEnhance.Contrast(Image.fromarray(file_image)) enhanced_image = enhanced_contrast.enhance(255) enhanced_data = np.array(enhanced_image) plot_functions.imshow(enhanced_image) plot_functions.show()''' # color_space = cv2.cvtColor(image_data, cv2.COLOR_RGB2HSV) # print(color_space) '''Create mask for white-ish pixels''' '''lower_background = np.array([150, 150, 150]) upper_background = np.array([255, 255, 255]) print(image_data) white_mask = cv2.inRange(image_data, lower_background, upper_background) white_mask = cv2.morphologyEx(white_mask, cv2.MORPH_OPEN, np.ones((3,3),np.uint8)) white_mask = cv2.morphologyEx(white_mask, cv2.MORPH_DILATE, np.ones((3, 3), np.uint8)) white_mask = white_mask / 255''' '''Create mask for black-ish pixels''' '''lower_background = np.array([0, 0, 0]) upper_background = np.array([25, 25, 25]) black_mask = cv2.inRange(image_data, lower_background, upper_background) black_mask = cv2.morphologyEx(black_mask, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8)) black_mask = cv2.morphologyEx(black_mask, cv2.MORPH_DILATE, np.ones((3, 3), np.uint8)) black_mask = black_mask / 255''' '''Add masks together''' '''background_mask = white_mask # Ensure no value is above 1 background_mask = np.clip(background_mask, 0, 1)''' copied_image_data = np.asarray(returned_image).copy() # background_mask = np.logical_not(background_mask) '''for row_index, [mask_row, image_row] in enumerate(zip(background_mask, copied_image_data)): # place black pixel on corresponding masked pixels # copied_image_data[row_index] = np.array([image_row[pixel] * int(mask_row[pixel]) for pixel in range(len(mask_row))]) # make pixel fully white on corresponding masked pixels copied_image_data[row_index] = np.array([np.array([255, 255, 255]) if int(mask_row[pixel]) else image_row[pixel] for pixel in range(len(mask_row))])''' '''Turn removed pixels red''' '''mask_image = Image.fromarray(copied_image_data) plot_functions.imshow(mask_image) plot_functions.show()''' trapezoid_data = copied_image_data.copy() enhanced_contrast = ImageEnhance.Contrast( Image.fromarray(trapezoid_data)) enhanced_image = enhanced_contrast.enhance(255) trapezoid_data = np.array(enhanced_image) '''Detect lines''' edges = cv2.Canny(trapezoid_data, 75, 150) lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, maxLineGap=1000) # print(lines) for line in lines: x1, y1, x2, y2 = line[0] if y1 == y2: cv2.line(copied_image_data, (x1, y1), (x2, y2), (255, 255, 255), 1) '''Trapezoid attempt''' # filters image bilaterally and displays it bilatImg = cv2.bilateralFilter(trapezoid_data, 5, 175, 175) # finds edges of bilaterally filtered image and displays it edgeImg = cv2.Canny(bilatImg, 75, 200) # gets contours (outlines) for shapes and sorts from largest area to smallest area contours, hierarchy = cv2.findContours(edgeImg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours = sorted(contours, key=cv2.contourArea, reverse=True) # drawing red contours on the image for con in contours: cv2.drawContours(trapezoid_data, con, -1, (255, 255, 255), 3) '''Detect corners''' dst = cv2.cornerHarris(edges, 30, 31, 0.001) dst = cv2.dilate(dst, None) ret, dst = cv2.threshold(dst, 0.01 * dst.max(), 255, 0) dst = np.uint8(dst) # find centroids ret, labels, stats, centroids = cv2.connectedComponentsWithStats( dst) # define the criteria to stop and refine the corners criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv2.cornerSubPix(edges, np.float32(centroids), (5, 5), (-1, -1), criteria) good_corners = [] for corner in corners: if (corner[1] < 1000) & (corner[1] > 650) & ( corner[0] > 250) & (corner[0] < 2250): good_corners.append(corner) cv2.circle(edges, (corner[0], corner[1]), 10, (255, 255, 255)) print(good_corners) if len(good_corners) >= 3: corner_combos = itertools.combinations(good_corners, 3) elif len(good_corners) > 1: corner_combos = itertools.combinations(good_corners, 2) best_corner_combo = None best_coef = np.inf for corner_combo in corner_combos: regression = LinearRegression().fit( np.array([corner[0] for corner in corner_combo]).reshape(-1, 1), np.array([corner[1] for corner in corner_combo])) if np.abs(regression.coef_) < best_coef: best_coef = np.abs(regression.coef_) best_corner_combo = np.array( [corner[1] for corner in corner_combo]) y_edge = int(round(np.mean(best_corner_combo))) edges = edges[y_edge:3000, 200:2200] copied_image_data = copied_image_data[y_edge:2500, 200:2200] trapezoid_data = trapezoid_data[y_edge:2500, 200:2200] # and double-checking the outcome cv2.imshow("linesEdges", edges) cv2.imshow("linesDetected", copied_image_data) cv2.imshow("Contours check", trapezoid_data) cv2.waitKey() cv2.destroyWindow("Contours check") # find the perimeter of the first closed contour perim = cv2.arcLength(contours[0], True) # setting the precision epsilon = 0.02 * perim # approximating the contour with a polygon approxCorners = cv2.approxPolyDP(contours[0], epsilon, True) # check how many vertices has the approximate polygon approxCornersNumber = len(approxCorners) for corners in approxCorners: cv2.circle(trapezoid_data, (corners[0], corners[1]), radius=10, color=(255, 255, 255), thickness=-1) cv2.imshow("Vertex position", trapezoid_data) cv2.waitKey() cv2.destroyWindow("Vertex position") cv2.imshow("linesEdges", edges) cv2.imshow("linesDetected", copied_image_data) cv2.waitKey(0) cv2.destroyAllWindows() def _on_exit(self, gui): if gui.program_running: gui.update() return WaitForDrop() else: return None class DragAndDropGUI: """ Object for a simple gui. """ def __init__(self, root): """ Initializing the SimpleGUI object. """ self.root = root w, h = root.winfo_screenwidth(), self.root.winfo_screenheight() self.root.geometry("%dx%d+0+0" % (w, h)) self.root.protocol("WM_DELETE_WINDOW", self.end_program) self.program_running = True def update(self): """ Update the GUI. :return: """ self.root.update_idletasks() self.root.update() return self.root def end_program(self): """ Ends the program. :return: """ if self.entry_sv.get() != " ": self.entry_sv.set(" ") else: self.entry_sv.set("!") self.root.destroy() self.program_running = False '''Initialize and run GUI object''' root = tkinterdnd2.Tk() # Maximize window while maintaining title bar gui = DragAndDropGUI(root) state_machine = StateMachine(initial_state=InitialState()) state_machine.run(gui)