From 82f4f36e967f0784bd8b48ba1a038afb0860949a Mon Sep 17 00:00:00 2001 From: aneuhmanh Date: Thu, 7 Aug 2025 20:55:27 +0300 Subject: [PATCH] first commit --- README.md | 34 +++++++++++++++ main.py | 111 +++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 + 3 files changed, 147 insertions(+) create mode 100644 README.md create mode 100644 main.py create mode 100644 requirements.txt diff --git a/README.md b/README.md new file mode 100644 index 0000000..c4279c1 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# BlazingConverter +#### супер блейзинг недоскрипт на пайтоне для конвертации изображений +--- +ИСПОЛЬЗОВАНИЕ: + +- wINDOWS: +main.exe `single`|`mass` `путь` `выходной формат (jpg, png, bmp, tiff, webp)` + + +- Нормальная система(Linux) & mAC: +main.py `single`|`mass` `путь` `выходной формат (jpg, png, bmp, tiff, webp)` + +ЗАВИСИМОСТИ: +- `pillow` + +- `qtdm` + +УСТАНОВКА ЗАВИСИМОСТЕЙ: +(пропускайте если используете `.exe`) +создание виртуального окружения: +- `python -m venv venv` + +активация виртуального окружения: +- Нормальная система(Linux) & mAC: + - `source venv/bin/activate` + +- wINDOWS + - Powershell: `.\venv\Scripts\Activate` + - CMD: `venv\Scripts\activate.bat` + +установка зависимостей: +- pip install -r requirements.txt + +--- diff --git a/main.py b/main.py new file mode 100644 index 0000000..3c0a2aa --- /dev/null +++ b/main.py @@ -0,0 +1,111 @@ +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 + python main.py single + +Поддерживаемые форматы вывода: + 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() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..658b481 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pillow==11.3.0 +tqdm==4.67.1