Add option --filesize, compress jpg below target size.
This commit is contained in:
parent
96b10126ec
commit
c3355b6277
1 changed files with 32 additions and 2 deletions
32
rejpg.py
32
rejpg.py
|
@ -18,6 +18,31 @@ log = vlogging.getLogger(__name__, 'rejpg')
|
|||
|
||||
PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
|
||||
def compress_to_filesize(image, target_size, *, exif=None):
|
||||
lower = 1
|
||||
lower_bio = None
|
||||
upper = 100
|
||||
current = 100
|
||||
while True:
|
||||
# print(lower, current, upper)
|
||||
if lower == (upper - 1):
|
||||
break
|
||||
bio = io.BytesIO()
|
||||
image.save(bio, format='jpeg', exif=exif, quality=current)
|
||||
bio.seek(0)
|
||||
size = len(bio.read())
|
||||
if size > target_size:
|
||||
upper = current
|
||||
if size <= target_size:
|
||||
lower = current
|
||||
lower_bio = bio
|
||||
current = (lower + upper) // 2
|
||||
|
||||
if lower_bio is None:
|
||||
raise RuntimeError(f'Could not compress below {target_size}')
|
||||
|
||||
return lower_bio
|
||||
|
||||
def rejpg_argparse(args):
|
||||
patterns = pipeable.input_many(args.patterns, skip_blank=True, strip=True)
|
||||
files = spinal.walk(recurse=args.recurse, glob_filenames=patterns)
|
||||
|
@ -28,11 +53,15 @@ def rejpg_argparse(args):
|
|||
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)
|
||||
|
||||
if args.filesize:
|
||||
target_size = bytestring.parsebytes(args.filesize)
|
||||
bytesio = compress_to_filesize(image, target_size, exif=exif)
|
||||
else:
|
||||
bytesio = io.BytesIO()
|
||||
image.save(bytesio, format='jpeg', exif=exif, quality=args.quality)
|
||||
|
||||
bytesio.seek(0)
|
||||
|
@ -56,6 +85,7 @@ def main(argv):
|
|||
|
||||
parser.add_argument('patterns', nargs='+', default={'*.jpg', '*.jpeg'})
|
||||
parser.add_argument('--quality', type=int, default=80)
|
||||
parser.add_argument('--filesize', type=str, default=None)
|
||||
parser.add_argument('--recurse', action='store_true')
|
||||
parser.set_defaults(func=rejpg_argparse)
|
||||
|
||||
|
|
Loading…
Reference in a new issue