Skip to content

Instantly share code, notes, and snippets.

@cceasy
Created October 27, 2018 07:45
Show Gist options
  • Select an option

  • Save cceasy/65fa3930f81d1055893192d2b2c00966 to your computer and use it in GitHub Desktop.

Select an option

Save cceasy/65fa3930f81d1055893192d2b2c00966 to your computer and use it in GitHub Desktop.

Revisions

  1. cceasy created this gist Oct 27, 2018.
    119 changes: 119 additions & 0 deletions resize_images.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,119 @@
    #!/usr/bin/env python

    import os
    from PIL import Image, ExifTags
    from shutil import copyfile

    orientation = 0x0112 # image exif info for Orientation 274
    device = 0x010f # image exif info for Make 271

    src_dir = 'todo'

    thumbnail_config = {
    'max_size': 50 * 1024, # 50 kB
    'min_wh': 400, # 0 measn not to resize height or width
    'min_quality': 20, # jpg quality
    'quality_fall': 5, # quality will decrease per step
    'bytes_quality': 220 * 1024, # every x byte get 1 quality decrease
    'debug': True,
    'output_dir': 'todo',
    }

    opt_config = {
    'max_size': 2 * 1024 * 1024, # 2 MB
    'min_wh': 1560, # 0 measn not to resize height or width
    'min_quality': 75, # jpg quality
    'quality_fall': 3, # quality will decrease per step
    'bytes_quality': 1024 * 1024, # every x byte get 1 quality decrease
    'debug': True,
    'output_dir': 'todo',
    }

    # config = thumbnail_config
    config = opt_config

    def init_exif_keys():
    global orientation
    global device
    for key in ExifTags.TAGS.keys():
    if ExifTags.TAGS[key] == 'Orientation':
    orientation = key
    elif ExifTags.TAGS[key] == 'Make':
    device = key


    def resize(src_path, output_path):

    max_size = config['max_size']
    min_wh = config['min_wh']
    min_quality = config['min_quality']
    quality_fall = config['quality_fall']
    bytes_quality = config['bytes_quality']
    debug = config['debug']

    if not os.path.exists(output_path):
    os.mkdir(output_path)
    files = list(os.listdir(src_path))
    print('⬇ resize and copy {} files from {} to {}'.format(len(files), src_path, output_path))
    for file in files:
    if debug:
    print('# process file', file)
    src_file = os.path.join(src_path, file)
    src_size = os.path.getsize(src_file)
    if os.path.isdir(src_file):
    continue
    if src_file.endswith('DS_Store'):
    os.remove(src_file)
    continue
    output_file = os.path.join(output_path, file)
    img = Image.open(src_file)
    img = process_exif(img)
    if (src_size > max_size):
    min_px = min(img.size)
    if min_px > min_wh:
    scale = min_px / float(min_wh)
    w, h = int(img.width / scale), int(img.height / scale)
    img = img.resize((w, h), Image.ANTIALIAS)
    quality = int(100 - src_size / bytes_quality)
    if quality < min_quality:
    quality = min_quality
    if debug:
    print('init quality is', quality)
    img.save(output_file, optimize=True, quality=quality)
    while os.path.getsize(output_file) > max_size and quality > min_quality:
    quality -= quality_fall
    if debug:
    print('+ adjust quality to', quality)
    img.save(output_file, optimize=True, quality=quality)
    img.close()
    else:
    copyfile(src_file, output_file)
    return len(files)

    def process_exif(image):
    if hasattr(image, '_getexif') and isinstance(image._getexif(), dict):
    exif = image._getexif()
    # if device in exif and exif[device] == 'Apple': # Canon XiaoMi Apple
    if orientation in exif:
    if exif[orientation] == 3:
    image = image.rotate(180, expand=True)
    elif exif[orientation] == 6:
    image = image.rotate(270, expand=True)
    elif exif[orientation] == 8:
    image = image.rotate(90, expand=True)
    return image

    if __name__ == '__main__':

    init_exif_keys()

    cnt = 0
    output_dir = config['output_dir']

    for file in os.listdir(src_dir):
    src_path = os.path.join(src_dir, file)
    if os.path.isdir(src_path):
    output_path = os.path.join(output_dir, file)
    cnt += resize(src_path, output_path)

    print('cnt:', cnt)