File indexing completed on 2024-05-12 16:58:37

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)