2025-08-07 20:55:27 +03:00

112 lines
3.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import sys
from pathlib import Path
from PIL import Image
from multiprocessing import Pool, cpu_count
from tqdm import tqdm
import time
SUPPORTED_INPUT_EXTS = {'.jpg', '.png', '.bmp', '.tiff', '.webp'}
SUPPORTED_OUTPUT_FORMATS = {'jpg', 'png', 'bmp', 'tiff', 'webp'}
def list_images(folder: Path):
return [f for f in folder.iterdir() if f.suffix.lower() in SUPPORTED_INPUT_EXTS and f.is_file()]
def normalize_format(fmt: str):
fmt = fmt.lower()
if fmt == 'jpg':
return 'jpeg'
return fmt
def convert_image(args):
in_path, out_path, out_format = args
try:
with Image.open(in_path) as img:
img.save(out_path, out_format.upper())
return (in_path.name, True, None)
except Exception as e:
return (in_path.name, False, str(e))
def print_usage():
print("""
Использование:
python main.py mass <input_folder> <output_format>
python main.py single <input_file> <output_format>
Поддерживаемые форматы вывода:
jpg, png, bmp, tiff, webp
""")
def main():
if len(sys.argv) < 4:
print_usage()
return
mode = sys.argv[1].lower()
input_path = Path(sys.argv[2]).resolve()
out_format = normalize_format(sys.argv[3])
if out_format not in SUPPORTED_OUTPUT_FORMATS:
print(f"Ошибка: формат '{out_format}' не поддерживается.")
print_usage()
return
output_dir = Path.cwd() / 'output'
output_dir.mkdir(exist_ok=True)
start_time = time.perf_counter()
if mode == 'mass':
if not input_path.is_dir():
print(f"Ошибка: {input_path} не папка.")
return
imgs = list_images(input_path)
if not imgs:
print(f"В папке {input_path} нет поддерживаемых изображений.")
return
print(f"Массовая конвертация {len(imgs)} файлов из {input_path} в {output_dir} с форматом {out_format}")
args_list = []
for in_path in imgs:
out_path = output_dir / (in_path.stem + '.' + out_format)
args_list.append((in_path, out_path, out_format))
max_workers = cpu_count()
with Pool(processes=max_workers) as pool:
results = []
with tqdm(total=len(args_list), bar_format='{l_bar}{bar} {n_fmt}/{total_fmt}') as pbar:
for res in pool.imap_unordered(convert_image, args_list):
results.append(res)
name, success, err = res
if success:
tqdm.write(f"[OK] {name}")
else:
tqdm.write(f"[ERR] {name}: {err}")
pbar.update()
elif mode == 'single':
if not input_path.is_file():
print(f"Ошибка: {input_path} не файл.")
return
out_path = output_dir / (input_path.stem + '.' + out_format)
print(f"Конвертация файла {input_path} в {out_path}")
name, success, err = convert_image((input_path, out_path, out_format))
if success:
print(f"[OK] {name}")
else:
print(f"[ERR] {name}: {err}")
else:
print_usage()
return
end_time = time.perf_counter()
elapsed = end_time - start_time
minutes, seconds = divmod(elapsed, 60)
milliseconds = (seconds - int(seconds)) * 1000
print(f"\nКонвертация заняла {int(minutes)} минут {int(seconds)} секунд {int(milliseconds)} миллисекунд.")
if __name__ == '__main__':
main()