File indexing completed on 2024-05-12 05:28:48
0001 #!/usr/bin/env python3 0002 0003 import logging 0004 from multiprocessing import cpu_count 0005 from multiprocessing.pool import Pool 0006 from pathlib import Path 0007 from itertools import chain 0008 from typing import Final 0009 0010 try: 0011 import PIL 0012 from PIL import Image 0013 except ImportError: 0014 logging.critical("Please install the python PIL library.") 0015 logging.critical("e.g.: python3 -m pip install PIL") 0016 exit() 0017 0018 sizes = { 0019 'horizontal': ( 0020 (5120, 2880), (3840, 2160), (3200, 2000), (3200, 1800), 0021 (2560, 1600), (2560, 1440), (1920, 1200), (1920, 1080), 0022 (1680, 1050), (1600, 1200), (1440, 900), (1366, 768), 0023 (1280, 1024), (1280, 800), (1024, 768), (440, 247) 0024 ), 0025 'vertical': ((720, 1440), (360, 720), (1080, 1920)) 0026 } 0027 0028 templates = { 0029 'horizontal': ('base_size.png', 'base_size.jpg'), 0030 'vertical': ('vertical_base_size.png', 'vertical_base_size.jpg') 0031 } 0032 0033 PIL_VERSION: Final = tuple(map(int, PIL.__version__.split("."))) 0034 0035 0036 def resize_and_save_image(file: Path, image: Image, width: int, height: int) -> None: 0037 """ 0038 Image.LANCZOS is deprecated since 9.1.0 https://pillow.readthedocs.io/en/stable/deprecations.html#constants 0039 """ 0040 logging.info(f'Generating {width}x{height}') 0041 0042 base_dir, extension = file.parent, file.suffix 0043 base_width, base_height = image.size 0044 0045 if width / height > base_width / base_height: 0046 crop = int(base_height - height / (width / base_width)) // 2 0047 box = (0, crop, base_width, base_height - crop) 0048 elif width / height < base_width / base_height: 0049 crop = int(base_width - width / (height / base_height)) // 2 0050 box = (crop, 0, base_width - crop, base_height) 0051 else: 0052 box = None 0053 0054 if PIL_VERSION >= (9, 1): 0055 resized_image = image.resize((width, height), Image.Resampling.LANCZOS, box) 0056 else: 0057 resized_image = image.resize((width, height), Image.LANCZOS, box) 0058 0059 resized_image.save(base_dir / f'{width}x{height}{extension}', 0060 quality=90, optimize=True, subsampling=1) 0061 0062 0063 argument_list: list[tuple] = [] 0064 0065 for orientation in ('horizontal', 'vertical'): 0066 for file in chain(*map(Path().rglob, templates[orientation])): 0067 image = Image.open(file) 0068 image.load(); 0069 for width, height in sizes[orientation]: 0070 argument_list.append((file, image, width, height)) 0071 0072 with Pool(processes=cpu_count()) as pool: 0073 pool.starmap(resize_and_save_image, argument_list)