Rewrite rejpg with argparse and preserve exif orientation.

master
voussoir 2020-12-23 20:05:35 -08:00
parent 3f858aefe7
commit 1eae1ae399
1 changed files with 62 additions and 30 deletions

View File

@ -1,48 +1,80 @@
''' '''
Recompress all jpg images in the current directory. Recompress all jpg images in the current directory.
Add /r to do nested directories as well.
''' '''
import argparse
from voussoirkit import bytestring
import io import io
import os import os
import PIL.ExifTags
import PIL.Image import PIL.Image
import PIL.ImageFile import PIL.ImageFile
import string import string
import sys import sys
from voussoirkit import bytestring
PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True
if '/r' in sys.argv: for (ORIENTATION_KEY, val) in PIL.ExifTags.TAGS.items():
from voussoirkit import spinal if val == 'Orientation':
walker = spinal.walk_generator() break
files = list(walker)
def rejpg_argparse(args):
if args.recurse:
from voussoirkit import spinal
walker = spinal.walk_generator()
files = list(walker)
else:
from voussoirkit import pathclass
files = pathclass.cwd().listdir()
files = [f for f in files if f.is_file]
files = [f for f in files if f.extension in ['.jpg', '.jpeg']]
files = [f.absolute_path for f in files] files = [f.absolute_path for f in files]
else: bytes_saved = 0
files = os.listdir() remaining_size = 0
files = [f for f in files if os.path.isfile(f)] for filename in files:
print(''.join(c for c in filename if c in string.printable))
bytesio = io.BytesIO()
i = PIL.Image.open(filename)
exif = i._getexif()
files = [f for f in files if any(ext in f.lower() for ext in ['.jpg', '.jpeg'])] # Preserve orientation according to exif
# Thank you Scabbiaza
# https://stackoverflow.com/a/26928142
if exif is None:
pass
elif exif[ORIENTATION_KEY] == 3:
i = i.rotate(180, expand=True)
elif exif[ORIENTATION_KEY] == 6:
i = i.rotate(270, expand=True)
elif exif[ORIENTATION_KEY] == 8:
i = i.rotate(90, expand=True)
bytes_saved = 0 i.save(bytesio, format='jpeg', quality=80)
remaining_size = 0
for filename in files:
print(''.join(c for c in filename if c in string.printable))
bytesio = io.BytesIO()
i = PIL.Image.open(filename)
i.save(bytesio, format='jpeg', quality=80)
bytesio.seek(0) bytesio.seek(0)
new_bytes = bytesio.read() new_bytes = bytesio.read()
old_size = os.path.getsize(filename) old_size = os.path.getsize(filename)
new_size = len(new_bytes) new_size = len(new_bytes)
remaining_size += new_size remaining_size += new_size
if new_size < old_size: if new_size < old_size:
bytes_saved += (old_size - new_size) bytes_saved += (old_size - new_size)
f = open(filename, 'wb') f = open(filename, 'wb')
f.write(new_bytes) f.write(new_bytes)
f.close() f.close()
print('Saved', bytestring.bytestring(bytes_saved)) print('Saved', bytestring.bytestring(bytes_saved))
print('Remaining are', bytestring.bytestring(remaining_size)) print('Remaining are', bytestring.bytestring(remaining_size))
def main(argv):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--recurse', dest='recurse', action='store_true')
parser.set_defaults(func=rejpg_argparse)
args = parser.parse_args(argv)
return args.func(args)
if __name__ == '__main__':
raise SystemExit(main(sys.argv[1:]))