refactor: Move image processing configuration to settings

Refactored image processing system to use centralized configuration in settings.IMAGE_PROCESSING_CONFIG instead of hardcoded values.

Changes:
- Added IMAGE_PROCESSING_CONFIG to settings with configurable sizes, formats, and quality
- Rewrote ImageProcessor to use dynamic configuration from settings
- Added support for multiple image formats (JPEG, WebP, PNG)
- Updated _save_image_version() to handle different formats and quality levels
- Added original image scaling (max 2160×2160) and square aspect ratio
- Updated ImageService to work with different file extensions (.jpg, .webp, .png)
- All parameters now easily configurable without code changes

Configuration:
- Original: JPEG, quality 100, max 2160×2160 (always square)
- Large: WebP, quality 90, 1200×1200
- Medium: WebP, quality 85, 600×600
- Thumbnail: WebP, quality 80, 200×200

Benefits:
- Flexible and maintainable configuration
- Smaller file sizes (WebP for resized images)
- Maximum quality for originals (JPEG 100)
- Square aspect ratio for better consistency

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-22 23:34:14 +03:00
parent a9b16bf212
commit f12fd18190
4 changed files with 529 additions and 62 deletions

View File

@@ -12,22 +12,58 @@ class ImageService:
Динамически строит URL на основе пути к оригинальному файлу.
"""
# Папки для разных размеров
SIZE_FOLDERS = {
'thumbnail': 'thumbnails',
'medium': 'medium',
'large': 'large',
'original': 'originals',
}
@staticmethod
def _get_config():
"""Получить конфигурацию из settings"""
return getattr(settings, 'IMAGE_PROCESSING_CONFIG', {})
@staticmethod
def _get_size_folders():
"""Получить папки для разных размеров из конфигурации"""
config = ImageService._get_config()
return config.get('folders', {
'thumbnail': 'thumbnails',
'medium': 'medium',
'large': 'large',
'original': 'originals',
})
@staticmethod
def _get_format_config(size_key):
"""Получить конфигурацию формата для заданного типа изображения"""
config = ImageService._get_config()
formats = config.get('formats', {})
return formats.get(size_key, {'format': 'JPEG', 'quality': 90})
@staticmethod
def _get_file_extension(size_key):
"""Получить расширение файла для заданного типа изображения"""
format_config = ImageService._get_format_config(size_key)
image_format = format_config.get('format', 'JPEG')
ext_map = {
'JPEG': 'jpg',
'WEBP': 'webp',
'PNG': 'png',
}
return ext_map.get(image_format, 'jpg')
@staticmethod
def get_url(original_image_path, size='medium'):
"""
Получает URL изображения нужного размера.
Работает с новым форматом имён файлов с поддержкой разных расширений:
- robot-50cm_1729611234567_original.jpg (JPEG, оригинал)
- robot-50cm_1729611234567_large.webp (WebP)
- robot-50cm_1729611234567_medium.webp (WebP)
- robot-50cm_1729611234567_thumbnail.webp (WebP)
Args:
original_image_path: Путь к оригинальному файлу (из models.image)
size: Размер ('original', 'thumbnail', 'medium', 'large')
Обычно это путь к файлу 'original'
Пример: products/originals/robot-50cm_1729611234567_original.jpg
size: Размер ('original', 'large', 'medium', 'thumbnail')
По умолчанию 'medium'
Returns:
@@ -48,8 +84,28 @@ class ImageService:
else:
base_path = 'products'
# Проверяем новый формат имени файла с расширением
# Поддерживаем jpg, webp, png расширения
if filename.endswith(('.jpg', '.webp', '.png')):
# Определяем расширение файла
file_ext = os.path.splitext(filename)[1] # .jpg, .webp и т.д.
filename_without_ext = filename[:-(len(file_ext))] # Имя без расширения
# Разделяем по последнему _ для получения base_filename и size_key
parts_of_name = filename_without_ext.rsplit('_', 1)
if len(parts_of_name) == 2:
base_filename, file_size_key = parts_of_name
# Это новый формат с явным указанием размера в имени
# Получаем расширение для целевого размера
target_ext = ImageService._get_file_extension(size)
# Меняем размер в имени файла и расширение
filename = f"{base_filename}_{size}.{target_ext}"
# Иначе оставляем как есть
# Строим новый путь
folder = ImageService.SIZE_FOLDERS.get(size, 'medium')
size_folders = ImageService._get_size_folders()
folder = size_folders.get(size, 'medium')
new_path = f"{base_path}/{folder}/{filename}"
# Возвращаем URL