Python code: Compress a folder of image
import os
from PIL import Image
def get_size_format(b, factor=1024, suffix="B"):
"""
Scale bytes to its proper byte format
e.g:
1253656 => '1.20MB'
1253656678 => '1.17GB'
"""
for unit in ["", "K", "M", "G", "T", "P", "E", "Z"]:
if b < factor:
return f"{b:.2f}{unit}{suffix}"
b /= factor
return f"{b:.2f}Y{suffix}"
def compress_img(image_name, new_size_ratio=0.9, quality=90, width=None, height=None, to_jpg=True):
# load the image to memory
img = Image.open(image_name)
# print the original image shape
print("[*] Image: ", image_name)
print("[*] Image shape:", img.size)
# get the original image size in bytes
image_size = os.path.getsize(image_name)
# print the size before compression/resizing
print("[*] Size before compression:", get_size_format(image_size))
if new_size_ratio < 1.0:
# if resizing ratio is below 1.0, then multiply width & height with this ratio to reduce image size
img = img.resize((int(img.size[0] * new_size_ratio), int(img.size[1] * new_size_ratio)), Image.ANTIALIAS)
# print new image shape
print("[+] New Image shape:", img.size)
elif width and height:
# if width and height are set, resize with them instead
img = img.resize((width, height), Image.ANTIALIAS)
# print new image shape
print("[+] New Image shape:", img.size)
# split the filename and extension
filename, ext = os.path.splitext(image_name)
# make new filename appending _compressed to the original file name
if to_jpg:
# change the extension to JPEG
new_filename = f"{filename}_compressed.jpg"
else:
# retain the same extension of the original image
new_filename = f"{filename}_compressed{ext}"
try:
# save the image with the corresponding quality and optimize set to True
img.save(new_filename, quality=quality, optimize=True)
except OSError:
# convert the image to RGB mode first
img = img.convert("RGB")
# save the image with the corresponding quality and optimize set to True
img.save(new_filename, quality=quality, optimize=True)
print("[+] New file saved:", new_filename)
# get the new image size in bytes
new_image_size = os.path.getsize(new_filename)
# print the new size in a good format
print("[+] Size after compression:", get_size_format(new_image_size))
# calculate the saving bytes
saving_diff = new_image_size - image_size
# print the saving percentage
print(f"[+] Image size change: {saving_diff/image_size*100:.2f}% of the original image size.")
def get_images(folder):
filelist = os.listdir(folder)
return filelist
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Simple Python script for compressing and resizing images")
parser.add_argument("folder", help="Target folder to compress and/or resize")
parser.add_argument("-j", "--to-jpg", action="store_true", help="Whether to convert the image to the JPEG format")
parser.add_argument("-q", "--quality", type=int, help="Quality ranging from a minimum of 0 (worst) to a maximum of 95 (best). Default is 90", default=90)
parser.add_argument("-r", "--resize-ratio", type=float, help="Resizing ratio from 0 to 1, setting to 0.5 will multiply width & height of the image by 0.5. Default is 1.0", default=1.0)
parser.add_argument("-w", "--width", type=int, help="The new width image, make sure to set it with the `height` parameter")
parser.add_argument("-hh", "--height", type=int, help="The new height for the image, make sure to set it with the `width` parameter")
args = parser.parse_args()
# print the passed arguments
files = get_images(args.folder)
count = 0
for image in files:
count = count + 1
compress_img(args.folder + "/" + image, args.resize_ratio, args.quality, args.width, args.height, args.to_jpg)
print("Compressed %d files", count)
What’s your Reaction?
+1
2
+1
+1