Skip to content

Commit

Permalink
Adds Batch mode and QoL Changes
Browse files Browse the repository at this point in the history
- Adds Batch mode
- Async thread for work
- Better Progress bar interactions
- Less freezing in the GUI, i hope
- Accurate duration (removed the 2 digit formatting)
  • Loading branch information
MechTechnology authored Jul 2, 2021
1 parent 2025b3f commit 589a356
Showing 1 changed file with 54 additions and 27 deletions.
81 changes: 54 additions & 27 deletions SmartStitchGUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import os
import time
import pickle
import threading

class SmartStitch(Tk):
def __init__(self, *args, **kwargs):
Expand All @@ -16,10 +17,12 @@ def __init__(self, *args, **kwargs):
# Global Variables
self.input_folder = StringVar()
self.output_folder = StringVar()
self.batch_mode = IntVar()
self.split_height = StringVar(value="5000")
self.senstivity = StringVar(value="90")
self.status = StringVar(value="Idle")
self.output_type = StringVar(value=".jpg")
self.num_of_inputs = 1
self.progress = ""
self.actionbutton = ""

Expand All @@ -41,7 +44,7 @@ def geticon(self, relative_path):
# return os.path.join(base_path, relative_path)
def SetupWindow(self):
# Sets up Title and Logo
self.title('SmartStitch by MechTechnology [1.6]')
self.title('SmartStitch by MechTechnology [1.7]')
self.iconbitmap(default=self.geticon("SmartStitchLogo.ico"))

# Sets Window Size, centers it on Launch and Prevents Resize.
Expand Down Expand Up @@ -76,7 +79,7 @@ def SaveCurrentSettings(self, *args):

settings_pickle = "settings.pickle"
with open(settings_pickle, 'wb') as settings_handle:
pickle.dump(settings, settings_handle)
pickle.dump(settings, settings_handle)

def SetupBrowseFrame(self):
# Browse Button and Input and Output Field
Expand All @@ -87,11 +90,13 @@ def SetupBrowseFrame(self):
browse_button = ttk.Button(browse_frame, text = 'Browse', command=self.BrowseToCommand)
output_label = ttk.Label(browse_frame, text = 'Output Path')
output_field = ttk.Entry(browse_frame, textvariable=self.output_folder)
batch_checkbox = ttk.Checkbutton(browse_frame, variable=self.batch_mode, text = 'Batch Mode [Input folder contains multiple chapter folders]')
browse_label.grid(row = 0,column = 0, sticky="new")
browse_field.grid(row = 1, column = 0, pady=(2,0), sticky="new")
browse_button.grid(row = 1,column = 1, padx=(15, 0), sticky="ne")
output_label.grid(row = 2, column = 0, sticky="new")
output_field.grid(row = 3, column = 0, columnspan=2, pady=(2,0), sticky="new")
batch_checkbox.grid(row = 4, column = 0, columnspan=2, pady=(2,0), sticky="new")
browse_frame.columnconfigure(0, weight=1)
return browse_frame

Expand Down Expand Up @@ -156,20 +161,27 @@ def SetupStatusFrame(self):
def SetupActionFrame(self):
action_frame = Frame(self)
self.progress = ttk.Progressbar(action_frame)
self.actionbutton = ttk.Button(action_frame, text = 'Start Process', command=self.RunStitchProcess)
self.actionbutton = ttk.Button(action_frame, text = 'Start Process', command=self.RunStitchProcessAsync)
self.progress.grid(row = 0, column = 0, columnspan = 2, pady=(2,0), sticky="new")
self.actionbutton.grid(row = 0, column = 2, padx=(15, 0), sticky="new")
action_frame.columnconfigure(0, weight=1)
action_frame.columnconfigure(1, weight=1)
action_frame.columnconfigure(2, weight=1)
return action_frame

def LoadImages(self):
def SetBatchFolders(self):
batch_input_folder = self.input_folder.get()
batch_output_folder = self.output_folder.get()
input_folders = [os.path.abspath(os.path.join(batch_input_folder, name)) for name in os.listdir(batch_input_folder) if os.path.isdir(os.path.join(batch_input_folder, name))]
output_folders = [os.path.abspath(os.path.join(batch_output_folder, name + " [Stitched]" )) for name in os.listdir(batch_input_folder) if os.path.isdir(os.path.join(batch_input_folder, name))]
return input_folders, output_folders

def LoadImages(self, foldername):
# Loads all image files in a given folder into a list of pillow image objects
images = []
if (self.input_folder.get() == ""):
if (foldername == ""):
return images
folder = os.path.abspath(str(self.input_folder.get()))
folder = os.path.abspath(str(foldername))
files = natsorted(os.listdir(folder))
if len(files) == 0:
return images
Expand Down Expand Up @@ -244,17 +256,18 @@ def SplitVertical(self, combined_img):
images.append(split_image)
return images

def SaveData(self, data):
def SaveData(self, data, foldername):
# Saves the given images/date in the output folder!
new_folder = str(self.output_folder.get())
new_folder = str(foldername)
if not os.path.exists(new_folder):
os.makedirs(new_folder)
imageIndex = 1
outputformat = self.output_type.get()
progress_value = self.progress['value']
for image in data:
image.save(new_folder + '/' + str(f'{imageIndex:02}') + outputformat, quality=100)
imageIndex += 1
progress_value = 40 + (60 * imageIndex/len(data))
progress_value += ((60 * 1/len(data)) / self.num_of_inputs)
self.progress['value'] = progress_value
Tk.update_idletasks(self)
return
Expand All @@ -275,28 +288,42 @@ def RunStitchProcess(self):
self.status.set("Working - Loading Image Files!")
self.progress['value'] = 0
Tk.update_idletasks(self)
images = self.LoadImages()
if len(images) == 0:
self.status.set("Idle - No Image Files Found!")
self.actionbutton['state'] = "normal"
return
self.status.set("Working - Combining Image Files!")
self.progress['value'] = 10
Tk.update_idletasks(self)
combined_image = self.CombineVertically(images)
self.status.set("Working - Slicing Combined Image into Finalized Images!")
self.progress['value'] = 20
Tk.update_idletasks(self)
final_images = self.SplitVertical(combined_image)
self.status.set("Working - Saving Finalized Images!")
self.progress['value'] = 40
Tk.update_idletasks(self)
self.SaveData(final_images)
input_folders = []
output_folders = []
if self.batch_mode.get() == 0:
input_folders.append(self.input_folder.get())
output_folders.append(self.output_folder.get())
else:
input_folders , output_folders = self.SetBatchFolders()
self.num_of_inputs = len(input_folders)
for folder in input_folders:
images = self.LoadImages(folder)
if len(images) == 0:
self.status.set("Idle - No Image Files Found!")
self.actionbutton['state'] = "normal"
return
self.status.set("Working - Combining Image Files!")
self.progress['value'] += (10 / self.num_of_inputs)
Tk.update_idletasks(self)
combined_image = self.CombineVertically(images)
self.status.set("Working - Slicing Combined Image into Finalized Images!")
self.progress['value'] += (10 / self.num_of_inputs)
Tk.update_idletasks(self)
final_images = self.SplitVertical(combined_image)
self.status.set("Working - Saving Finalized Images!")
self.progress['value'] += (20 / self.num_of_inputs)
Tk.update_idletasks(self)
outfolder = output_folders[input_folders.index(folder)]
self.SaveData(final_images, outfolder)
end = time.time()
delta = end - start
self.status.set("Idle - Files successfully stitched in " + str(f'{delta:.2}') + "sec!")
self.status.set("Idle - Files successfully stitched in " + str(delta) + "sec!")
self.progress['value'] = 100
self.actionbutton['state'] = "normal"

def RunStitchProcessAsync(self):
workthread = threading.Thread(target=self.RunStitchProcess)
workthread.start()


SmartStitch().mainloop()

0 comments on commit 589a356

Please sign in to comment.