Skip to content

Commit 74505a1

Browse files
author
dn0z
committed
Added the opening, resizing and saving logic
1 parent 4bef99a commit 74505a1

File tree

1 file changed

+108
-12
lines changed

1 file changed

+108
-12
lines changed

bir.py

Lines changed: 108 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# https://github.com/dn0z/Batch-Image-Resize
66

77
import os
8-
8+
from PIL import Image
99
from tkinter import *
1010
from tkinter import ttk
1111
from tkinter import filedialog
@@ -21,8 +21,8 @@ def set_properties_defaults(self):
2121
self.selected_directory.set("No directory selected")
2222
self.export_properties["width"].set("width px")
2323
self.export_properties["height"].set("height px")
24-
self.export_properties["type"].set("PNG") # default export type
25-
self.overwrite_original.set(False) # default is disabled
24+
self.export_properties["type"].set("PNG") # default export type
25+
self.overwrite_original.set(False) # default is disabled
2626

2727
def confirm_settings(self):
2828
"""
@@ -37,7 +37,7 @@ def confirm_settings(self):
3737
confirm_msg += "\nResize images to: " + self.export_properties["width"].get()
3838
confirm_msg += "x" + self.export_properties["height"].get() + " px"
3939
confirm_msg += "\nOverwrite original: "
40-
if self.overwrite_original:
40+
if self.overwrite_original.get():
4141
confirm_msg += "YES"
4242
else:
4343
confirm_msg += "NO"
@@ -46,8 +46,81 @@ def confirm_settings(self):
4646

4747
return messagebox.askyesno("Export confirmation", confirm_msg)
4848

49-
def export(self):
50-
print("Exporting")
49+
def is_image(self, filename):
50+
"""
51+
Checks if a filename is an image (png, jpg or jpeg, case insensitive)
52+
53+
:param filename: The filename (as a string)
54+
:return: `True` if the given filename is an image, or `False` if it's not
55+
"""
56+
57+
file = filename.lower()
58+
return file.endswith(".png") or file.endswith(".jpg") or file.endswith(".jpeg")
59+
60+
def get_filename_with_type(self, filename, file_type, suffix=""):
61+
"""
62+
Get a filename and return it with the given suffix and the correct file extension for the given type
63+
64+
:param filename: The filename (e.g. "image_file.jpg")
65+
:param file_type: The file type (e.g. "PNG")
66+
:param suffix: An optional string to place between the name and the extension of the file (default is "")
67+
:return: the filename with the correct extension for the given type (e.g. "image_file.png")
68+
"""
69+
70+
extension = filename.split(".")[-1]
71+
return filename[:-len(extension)] + suffix + "." + file_type.lowercase()
72+
73+
def export_file(self, path, name, width, height, export_type, overwrite):
74+
"""
75+
Open, resize and save an image with the given properties
76+
77+
:param path: The path to the directory where the image is located (without the image filename)
78+
:param name: The filename of the image we want to export
79+
:param width: The new width we want to resize to
80+
:param height: The new height we want to resize to
81+
:param export_type: The file type we want to save to (we ignore it if `overwrite` is `True`)
82+
:param overwrite: Whether we want to overwrite the original files or not
83+
"""
84+
85+
img_path = os.path.join(path, name)
86+
87+
# open the given image and resize it
88+
img = Image.open(img_path)
89+
img = img.resize((width, height), Image.ANTIALIAS)
90+
91+
# set the destination image file we want to save
92+
dest_img_name = self.get_filename_with_type(name, export_type, "_resized")
93+
if overwrite:
94+
dest_img_name = name
95+
96+
# save the resized/converted image
97+
print("Save to " + os.path.join(path, dest_img_name))
98+
# img.save(os.path.join(path, dest_img_name))
99+
100+
def init_export(self):
101+
"""
102+
Export all the images in the selected directory
103+
104+
When `self.init_export()` is called, everything is ready to resize and export images
105+
This loops through all the files in the given directory and calls `self.export_file()`
106+
for the actual opening, resizing and saving of the files
107+
"""
108+
109+
# final export settings
110+
directory_path = self.selected_directory.get()
111+
width = int(self.export_properties["width"].get())
112+
height = int(self.export_properties["height"].get())
113+
export_type = self.export_properties["type"].get()
114+
overwrite = self.overwrite_original.get()
115+
116+
# loop through the files in the given directory and export any image files
117+
for path, subdirs, files in os.walk(directory_path):
118+
for name in files:
119+
if self.is_image(name):
120+
self.export_file(path, name, width, height, export_type, overwrite)
121+
122+
# at this point, we are done with our exports, display a success message
123+
messagebox.showinfo("Exports completed", "All images were exported successfully")
51124

52125
def export_button_handler(self):
53126
"""
@@ -68,9 +141,16 @@ def export_button_handler(self):
68141
"The directory \"" + selected_directory + "\" does not exist")
69142
else:
70143
# Directory exists
71-
if self.confirm_settings():
72-
# Settings confirmed, we are ready to export
73-
self.export()
144+
if (not self.export_properties["width"].get().isdigit()) or \
145+
(not self.export_properties["height"].get().isdigit()):
146+
# Dimensions are not digits
147+
messagebox.showerror("Invalid dimensions",
148+
"Width and height must be integers")
149+
else:
150+
# Dimensions are digits
151+
if self.confirm_settings():
152+
# Settings confirmed, we are ready to export
153+
self.init_export()
74154

75155
def browse_for_directory(self):
76156
"""
@@ -80,6 +160,19 @@ def browse_for_directory(self):
80160

81161
self.selected_directory.set(filedialog.askdirectory())
82162

163+
def toggle_save_as_dropdown(self):
164+
"""
165+
Change the state of `self.save_as_dropdown` based on `self.overwrite_original`
166+
167+
The dropdown should be enabled when `self.overwrite_original` is set to `False`
168+
and disabled when `self.overwrite_original` is set to `True`
169+
"""
170+
171+
if self.overwrite_original.get():
172+
self.save_as_dropdown.configure(state="disabled")
173+
else:
174+
self.save_as_dropdown.configure(state="enabled")
175+
83176
def create_widgets(self):
84177
"""
85178
Create the UI elements
@@ -118,19 +211,20 @@ def create_widgets(self):
118211
save_as_label = Label(main_container, text="Save as:", font=font_medium)
119212
save_as_label.grid(row=3, column=0, sticky="e")
120213

121-
save_as_dropdown = ttk.OptionMenu(main_container,
214+
self.save_as_dropdown = ttk.OptionMenu(main_container,
122215
self.export_properties["type"],
123216
self.export_properties["type"].get(),
124217
"PNG",
125218
"JPEG")
126-
save_as_dropdown.grid(row=3, column=1, sticky="we", padx=2)
219+
self.save_as_dropdown.grid(row=3, column=1, sticky="we", padx=2)
127220

128221
# Overwrite original
129222
overwrite_checkbox = ttk.Checkbutton(main_container,
130223
text="Overwrite original",
131224
variable=self.overwrite_original,
132225
onvalue=True,
133-
offvalue=False)
226+
offvalue=False,
227+
command=self.toggle_save_as_dropdown)
134228
overwrite_checkbox.grid(row=4, column=0, columnspan=2, sticky="w")
135229

136230
# Export
@@ -150,6 +244,8 @@ def __init__(self, parent=None):
150244
Frame.__init__(self, parent)
151245

152246
# properties
247+
self.save_as_dropdown = None
248+
153249
self.selected_directory = StringVar(self)
154250
self.overwrite_original = BooleanVar(self)
155251
self.export_properties = {

0 commit comments

Comments
 (0)