Created
May 9, 2021 07:42
-
-
Save Bruno02468/77e7998e58c3dd7ac3d81ac70e065607 to your computer and use it in GitHub Desktop.
script for batch fixing image dimensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# fix_images.py | |
# author: bruno borges paschoalinoto | |
# no rights reserved | |
# written for my friend @LucasGiannella | |
import sys, os, math | |
from itertools import repeat | |
try: | |
from PIL import Image | |
except: | |
print("Pillow does not seem to be installed. Try running:") | |
print(" python3 -m pip install --upgrade Pillow") | |
print("to install it.") | |
sys.exit(1) | |
EXTS = [ | |
".jpg", ".jpeg", ".png", ".gif", ".tiff", ".tif", ".bmp", ".dib" | |
] | |
def fiximg(args): | |
fn, target_dim = args | |
img = Image.open(fn) | |
corrs = [] | |
if img.size[0] < img.size[1]: | |
corrs.append("rotation") | |
img = img.rotate(90) | |
w, h = img.size | |
wj, hj = target_dim | |
if w < wj: | |
corrs.append("stretch to fit width") | |
img = img.resize((wj, h*wj//w)) | |
w, h = img.size | |
if h < hj: | |
corrs.append("stretch to fit height") | |
img = img.resize((w*hj//h, hj)) | |
w, h = img.size | |
if (w, h) != (wj, hj): | |
left = (w - wj)//2 | |
top = (h - hj)//2 | |
right = (w + wj)//2 | |
bottom = (h + hj)//2 | |
img = img.crop((left, top, right, bottom)) | |
corrs.append("center cut") | |
if len(corrs): | |
img.save(fn) | |
s = ", ".join(corrs) | |
print(f"Image {fn} required: {s}.") | |
return True | |
else: | |
print(f"Image {fn} was already the right size.") | |
return False | |
def fixdir(dirpath, target_dim, num_threads=1): | |
print(f"Fixing images in {dirpath} with {num_threads} threads.\n") | |
isimg = lambda p: any([ext in p for ext in EXTS]) | |
fs = map(lambda f: os.path.join(dirpath, f), os.listdir(dirpath)) | |
imgs = list(zip(filter(isimg, fs), repeat(target_dim))) | |
if num_threads == 1: | |
my_map = map | |
else: | |
from multiprocessing import Pool | |
my_map = Pool(num_threads).map | |
total = sum(my_map(fiximg, imgs)) | |
print(f"\nDone! Saw {len(imgs)} images, {total} out of which were changed.") | |
return total | |
def main(argc, argv): | |
if argc < 4: | |
print("Specify directory, width and height.") | |
return 1 | |
_, dirpath, wj, hj = argv[:4] | |
try: | |
wj = int(wj) | |
hj = int(hj) | |
if wj < 1 or hj < 1: | |
raise ValueError("Width and height need both be POSITIVE integers.") | |
except ValueError as ve: | |
print(ve) | |
return 1 | |
try: | |
from multiprocessing import cpu_count | |
cc = cpu_count() | |
except: | |
cc = 1 | |
num_threads = (cc - 1) if cc > 1 else 1 | |
fixdir(dirpath, (wj, hj), num_threads=num_threads) | |
return 0 | |
if __name__ == "__main__": | |
from sys import argv, exit | |
exit(main(len(argv), argv)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment