cmd/rejpg.py
Ethan Dalool 4a9051e617
Big migrations and linting.
With pathclass.glob_many, we can clean up and feel more confident
about many programs that use pipeable to take glob patterns.

Added return 0 to all programs that didn't have it, so we have
consistent and explicit command line return values.

Other linting and whitespace.
2021-09-23 23:42:45 -07:00

66 lines
1.9 KiB
Python

'''
Recompress all jpg images in the current directory.
'''
import argparse
import io
import os
import PIL.Image
import PIL.ImageFile
import sys
from voussoirkit import bytestring
from voussoirkit import imagetools
from voussoirkit import pipeable
from voussoirkit import spinal
from voussoirkit import vlogging
log = vlogging.getLogger(__name__, 'rejpg')
PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True
def rejpg_argparse(args):
patterns = pipeable.input_many(args.patterns, skip_blank=True, strip=True)
files = spinal.walk(recurse=args.recurse, glob_filenames=patterns)
files = [f.absolute_path for f in files]
bytes_saved = 0
remaining_size = 0
for filename in files:
log.info('Processing %s.', filename)
bytesio = io.BytesIO()
image = PIL.Image.open(filename)
(image, exif) = imagetools.rotate_by_exif(image)
image.save(bytesio, format='jpeg', exif=exif, quality=args.quality)
bytesio.seek(0)
new_bytes = bytesio.read()
old_size = os.path.getsize(filename)
new_size = len(new_bytes)
remaining_size += new_size
if new_size < old_size:
bytes_saved += (old_size - new_size)
f = open(filename, 'wb')
f.write(new_bytes)
f.close()
log.info('Saved', bytestring.bytestring(bytes_saved))
log.info('Remaining are', bytestring.bytestring(remaining_size))
return 0
@vlogging.main_decorator
def main(argv):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('patterns', nargs='+', default={'*.jpg', '*.jpeg'})
parser.add_argument('--quality', type=int, default=80)
parser.add_argument('--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:]))