From cb6368a51eb96471e1722243a2c6252d21462e4e Mon Sep 17 00:00:00 2001 From: aneuhmanh Date: Wed, 30 Jul 2025 17:29:48 +0300 Subject: [PATCH] first commit --- .gitignore | 2 ++ README.md | 28 ++++++++++++++++++++++++ conv.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 16 ++++++++++++++ requirements.txt | 1 + 5 files changed, 104 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 conv.py create mode 100644 main.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..82adb58 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +venv diff --git a/README.md b/README.md new file mode 100644 index 0000000..f7e4e55 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# image converter + +## установка +создание виртуального окружения: +- python -m venv venv + +активация виртуального окружения: +windows: +- Powershell: `.\venv\Scripts\Activate` +- CMD: `venv\Scripts\activate.bat` + +linux&mac: +- ` source venv/bin/activate` + +Установка зависимостей: +- `pip install -r requirements.txt` + +запуск: +-` python main.py` + +## использование +`input original format` оригинальный формат конвертируемых файлов + +`input target format` формат, в который будет конверт + +`select mode (single or mass)` +- single - указываете точный путь до файла +- mass - указываете путь до каталога с изображениями diff --git a/conv.py b/conv.py new file mode 100644 index 0000000..544801c --- /dev/null +++ b/conv.py @@ -0,0 +1,57 @@ +import os +from PIL import Image +from concurrent.futures import ThreadPoolExecutor + +class Converter: + def convert(self, original_format, target_format, path, mode): + target_format = target_format.lower() + original_format = original_format.lower() + + SUPPORTED_FORMATS = {"jpg", "jpeg", "png", "webp", "bmp", "tiff", "gif"} + if target_format not in SUPPORTED_FORMATS: + print(f"Unsupported format: {target_format}") + return + + if mode == "single": + img = Image.open(path) + filename, _ = os.path.splitext(path) + + if target_format in ("jpg", "jpeg"): + img = img.convert('RGB') + img.save(f"{filename}.{target_format}", "JPEG") + else: + img.save(f"{filename}.{target_format}", target_format.upper()) + + print("Done!") + + elif mode == "mass": + result_dir = os.path.join(path, "result") + os.makedirs(result_dir, exist_ok=True) + + images = [ + f for f in os.listdir(path) + if f.lower().endswith(f".{original_format}") + ] + + print("In queue:", images, "\n") + + def process_image(filename): + try: + img = Image.open(os.path.join(path, filename)) + name, _ = os.path.splitext(filename) + save_path = os.path.join(result_dir, f"{name}.{target_format}") + + if target_format in ("jpg", "jpeg"): + img = img.convert("RGB") + img.save(save_path, "JPEG") + else: + img.save(save_path, target_format.upper()) + + print(f"{filename} Done!") + except Exception as e: + print(f"{filename} failed: {e}") + + with ThreadPoolExecutor() as executor: + executor.map(process_image, images) + +converter = Converter() diff --git a/main.py b/main.py new file mode 100644 index 0000000..44fa86b --- /dev/null +++ b/main.py @@ -0,0 +1,16 @@ +from conv import converter + +while True: + original_format = input("Input original format: ") + target_format = input("Input target format: ") + mode = input("Select mode (single or mass): ").strip().lower() + + if mode == "single": + path = input("Input path to picture: ").strip() + else: + path = input("Input path to folder: ").strip() + + try: + converter.convert(original_format, target_format, path, mode) + except Exception as e: + print(f"Error: {e}") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c519fe2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pillow==11.3.0