Skip to content

Instantly share code, notes, and snippets.

@brakkum
Last active November 12, 2019 06:33
Show Gist options
  • Save brakkum/4aff9c6711d718bd5af50bae6368b6fd to your computer and use it in GitHub Desktop.
Save brakkum/4aff9c6711d718bd5af50bae6368b6fd to your computer and use it in GitHub Desktop.
A Python script that is supplied a directory, and recursively goes through said directory and compresses all photos/videos it finds of types specified in file.
from moviepy.editor import VideoFileClip, vfx
from PIL import Image
import imageio
import shutil
import imghdr
import numpy
import rawpy
import time
import sys
import os
# no dir provided
if len(sys.argv) <= 1:
print("give me a dir")
exit()
_dir = sys.argv[1]
# bad dir
if not os.path.isdir(_dir):
print("give me a single dir that exists")
exit()
# current dir
elif _dir.startswith("."):
print("plz no parent dir shenanigans")
exit()
if _dir[len(_dir) - 1] == "/":
_dir = _dir[:-1]
# what makes new dir unique
append = "-copy-{}".format(time.time())
# dir where copies are saved
new_dir = "{}{}".format(_dir, append)
# this shouldn't happen, but if copy dir exists
# destroy it
if os.path.isdir(new_dir):
shutil.rmtree(new_dir, ignore_errors=True)
# make dir for copies
os.mkdir(new_dir)
# max width or height
max_image_dimension = 1200, 1200
# replace first instance of dir supplied
# to the dir name where copies are kept
def get_new_copies_dir_name(path):
return path.replace(_dir, new_dir, 1)
# log to an error file
def log_error(err):
with open("dup_errors_{}".format(new_dir), mode="a+") as err_file:
err_file.writelines("{}\n".format(err))
# recursive func to traverse dirs and convert
# photos into small jpgs
def convert_photos_in_dir(_next_dir):
print("Next Dir: {}".format(_next_dir))
# get copies dir name for current directory
_new_photos_dir = get_new_copies_dir_name(_next_dir)
# current dir being converted
_this_dir = _next_dir
# mkdir in copies dir
if not os.path.exists(_new_photos_dir):
os.mkdir(_new_photos_dir)
# loop through them files
for file in os.listdir(_this_dir):
# full file path including given dir
_this_file = "{}/{}".format(_this_dir, file)
# file is dir, recurse
if (os.path.isdir(_this_file)):
convert_photos_in_dir(_this_file)
# not a dir, check if valid file we want
else:
compressed_file_types = [".jpeg", ".jpg", ".png"]
raw_file_types = [ ".nef", ".orf"]
tiff_file_types = [".tif", ".tiff"]
video_file_types = [".mp4", ".mov"]
file_ext = os.path.splitext(file)[1].lower()
# raw files
if file_ext in raw_file_types:
print("Photo {}".format(_this_file))
try:
with rawpy.imread(_this_file) as photo:
temp_file = "{}/{}.tiff".format(_new_photos_dir, file)
imageio.imsave(temp_file, photo.postprocess())
with Image.open(temp_file) as temp_photo:
out_file = "{}/{}-raw.jpg".format(_new_photos_dir, file)
temp_photo.thumbnail(max_image_dimension, Image.ANTIALIAS)
temp_photo.save(out_file, "JPEG")
os.remove(temp_file)
except:
print("Error: {}".format(_this_file))
log_error(_this_file)
# already compressed files
elif file_ext in compressed_file_types:
print("Photo {}".format(_this_file))
try:
with Image.open(_this_file) as photo:
photo.thumbnail(max_image_dimension, Image.ANTIALIAS)
photo.save("{}/{}".format(_new_photos_dir, file), "JPEG")
except:
print("Error: {}".format(_this_file))
log_error(_this_file)
# tiffs
elif file_ext in tiff_file_types:
print("Photo {}".format(_this_file))
try:
with Image.open(_this_file) as tiff_file:
tiff_array = numpy.array(tiff_file)
im = Image.fromarray(tiff_array)
im = im.convert("RGB")
im.thumbnail(max_image_dimension, Image.ANTIALIAS)
im.save("{}/{}.jpg".format(_new_photos_dir, file), "JPEG")
except:
print("Error: {}".format(_this_file))
log_error(_this_file)
# video files
elif file_ext in video_file_types:
try:
video = VideoFileClip(_this_file).fx(vfx.resize, width=1000)
out_file = "{}/{}".format(_new_photos_dir, file)
video.write_videofile(out_file,
preset="veryslow",
codec="libx264",
audio_codec="aac",
temp_audiofile="temp-audio.m4a",
remove_temp=True
)
except:
print("Error: {}".format(_this_file))
log_error(_this_file)
# pngs
elif file_ext in png_types:
print("Photo {}".format(_this_file))
try:
with Image.open(_this_file) as photo:
photo.thumbnail(max_image_dimension, Image.ANTIALIAS)
photo.save("{}/{}".format(_new_photos_dir, file), "PNG")
except:
print("Error: {}".format(_this_file))
log_error(_this_file)
# start at given dir
convert_photos_in_dir(_dir)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment