Skip to content

Instantly share code, notes, and snippets.

@tigerhawkvok
Created July 27, 2021 23:24
Show Gist options
  • Save tigerhawkvok/405089a33961f56b9739258c14d7ca48 to your computer and use it in GitHub Desktop.
Save tigerhawkvok/405089a33961f56b9739258c14d7ca48 to your computer and use it in GitHub Desktop.
Optimize images in a directory to reasonable quality without killing space
#!python3
"""
Opens all .jpg files in a folder and
downsamples them to maximum 1280 pixels wide
and quality level 75
"""
import glob
import os
from skimage.io import imread, imsave
from skimage.transform import rescale
import numpy as np
IGNORE_OPTIMIZE_LIST = frozenset([
"logo.png",
])
def _getImage(filePath):
"""
Tidy file return
"""
try:
if os.path.basename(filePath) in IGNORE_OPTIMIZE_LIST:
return None
return imread(filePath).astype(np.uint8)
except Exception: #pylint: disable= broad-except
return None
def downscaleJPGs(relativeDir:str= "./", maxResolution:int= 1280):
"""
Opens all .jpg files in a folder and downscale them to
maxResolution
"""
for jpgFile in glob.glob(os.path.join(relativeDir, '*.jpg')):
img = _getImage(jpgFile)
if img is None:
continue
scale = maxResolution / max(img.shape[0], img.shape[1])
if scale >= 1:
print(f"{jpgFile} OK size")
continue
print(f"Checking {jpgFile}")
img = rescale(img, scale, anti_aliasing= True, preserve_range= True, multichannel= True).astype(np.uint8)
try:
imsave(jpgFile, img)
except Exception as e: #pylint: disable= broad-except
print(f">> Failed to convert {jpgFile} of shape {img.shape}: {e}")
def optimizePNGs(relativeDir:str= "./", maxResolution:int= 1280):
"""
Call this function to optimize all .png files in a folder
"""
validPNG = set()
for pngFile in glob.glob(os.path.join(relativeDir, '*.png')):
img = _getImage(pngFile)
if img is None:
continue
scale = maxResolution / max(img.shape[0], img.shape[1])
if scale >= 1:
print(f"{pngFile} OK size")
validPNG.update([pngFile])
continue
print(f"Resizing {pngFile}")
img = rescale(img, scale, anti_aliasing= True, preserve_range= True, multichannel= True).astype(np.uint8)
try:
imsave(pngFile, img)
validPNG.update([pngFile])
except Exception as e: #pylint: disable= broad-except
print(f">> Failed to convert {pngFile} of shape {img.shape}: {e}")
# Now call optiPNG locally to optimize the rescaled images
for pngFile in validPNG:
print(f"Optimizing {pngFile}")
cmd = f"optipng -o5 -v {pngFile}"
os.system(cmd)
if __name__ == "__main__":
downscaleJPGs()
optimizePNGs()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment