Skip to content

Commit a6a70eb

Browse files
authored
Merge pull request larymak#301 from Rockwell70/main
New program for automatically resizing digital images.
2 parents 14e72a5 + 3389c9f commit a6a70eb

File tree

3 files changed

+168
-0
lines changed

3 files changed

+168
-0
lines changed

AUTOMATION/PhotoResizing/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Photo Resizing
2+
3+
### Description
4+
5+
I built this program because my company needs all employee badge photos to be the same size for
6+
posting in the employee directory. Photos are taken at multiple sites using different cameras,
7+
resulting in multiple photos of different sizes each week.
8+
9+
This program automates the process resizing each photo and saving it in a specific directory.
10+
11+
### Functionality
12+
- Image file resizing (of course!)
13+
- Archiving
14+
- Directory clean-up
15+
16+
### Instructions
17+
Simply pip install the requirements.txt and run!
18+
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
"""
2+
This program retrieves photos, standardizes their size, then renames and
3+
saves the resized photos in a new directory. Old photos are deleted,
4+
and an email is sent to the user indicating whether or not the
5+
operation was successful.
6+
"""
7+
8+
9+
import collections
10+
import os
11+
import glob
12+
import shutil
13+
import gc
14+
import threading, time
15+
from time import time
16+
from functools import wraps
17+
from pathlib import Path
18+
from PIL import Image
19+
import win32com.client as win32
20+
21+
22+
target = 'folder to save resized photos'
23+
archive_path = 'folder to save original photos'
24+
25+
26+
27+
28+
def main():
29+
process_sf_photos()
30+
31+
32+
def count_files_to_resize():
33+
global c
34+
global d
35+
c = collections.Counter(p.suffix for p in Path.cwd().glob('*.jpg'))
36+
d = c['.jpg']
37+
print(f'There are {d} files to resize.')
38+
39+
40+
def resize():
41+
new_size = (180, 240)
42+
global file_count
43+
file_count = 0
44+
for i in Path.cwd().iterdir():
45+
if i.suffix == '.jpg':
46+
file = Image.open(i.name)
47+
file = file.resize(new_size)
48+
file.save(f'{target}' + i.name[:-4] + '.jpg')
49+
file_count += 1
50+
print(f'{file_count} images were resized', '.....', sep='\n')
51+
52+
53+
# Copies each re-sized file into archive folder
54+
def copy_to_archive():
55+
global copy_count
56+
copy_count = 0
57+
print('Copying files to SubSFPhotos - Archive...')
58+
for fn in glob.glob(os.path.join(target, '*.jpg')):
59+
shutil.copy(fn, archive_path)
60+
copy_count += 1
61+
62+
print('Finished! ', f'{copy_count} files copied.', '.....', sep='\n')
63+
64+
65+
def delete_old_files():
66+
global delete_count
67+
delete_count = 0
68+
print('Deleting old files...')
69+
os.chdir(target)
70+
for i in Path.cwd().iterdir():
71+
if i.suffix == '.jpg':
72+
os.remove(i.name)
73+
delete_count += 1
74+
print('Finished!', f'{delete_count} files deleted.', '.....', sep='\n')
75+
76+
77+
def thread_resize():
78+
threadResize = threading.Thread(target=resize)
79+
threadResize.start()
80+
threadResize.join()
81+
82+
83+
def thread_copy():
84+
threadCopy = threading.Thread(target=copy_to_archive)
85+
threadCopy.start()
86+
threadCopy.join()
87+
88+
89+
def thread_delete():
90+
threadCopy = threading.Thread(target=delete_old_files)
91+
threadCopy.start()
92+
threadCopy.join()
93+
94+
95+
def good_email():
96+
outlook = win32.gencache.EnsureDispatch('Outlook.Application')
97+
new_mail = outlook.CreateItem(0)
98+
new_mail.Subject = "Photos resized with no problems"
99+
message = f'Number of files to resize: {d}.\n{file_count} were resized.\n' \
100+
f'{copy_count} files were copied.\n{delete_count} files were deleted. '
101+
new_mail.Body = message
102+
new_mail.To = to_email
103+
new_mail.Send()
104+
105+
106+
def bad_email():
107+
outlook = win32.gencache.EnsureDispatch('Outlook.Application')
108+
new_mail = outlook.CreateItem(0)
109+
new_mail.Subject = "Photo resize error."
110+
message = "There was an error in resizing the images."
111+
new_mail.Body = message
112+
new_mail.To = to_email
113+
new_mail.Send()
114+
115+
116+
def timer(f):
117+
@wraps(f)
118+
def wrapper(*args, **kwargs):
119+
start = time()
120+
result = f(*args, **kwargs)
121+
end = time()
122+
print(f'Process runs in {format(end - start)} seconds.')
123+
return result
124+
125+
return wrapper
126+
127+
128+
@timer
129+
def process_sf_photos():
130+
try:
131+
count_files_to_resize()
132+
thread_resize()
133+
thread_copy()
134+
thread_delete()
135+
gc.collect()
136+
except Exception as x:
137+
print(f"Looks like we have a problem: {type(x)} -> {x}")
138+
# bad_email()
139+
140+
141+
if __name__ == '__main__':
142+
run = 1
143+
if run == 1:
144+
main()
145+
else:
146+
print("Program didn't run. Set 'run' to 1 to run it.")
147+
148+
gc.collect()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Pillow==9.2.0
2+
win32-setctime==1.1.0

0 commit comments

Comments
 (0)