Created
October 27, 2018 07:45
-
-
Save cceasy/65fa3930f81d1055893192d2b2c00966 to your computer and use it in GitHub Desktop.
Revisions
-
cceasy created this gist
Oct 27, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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)