Spaces:
Runtime error
Runtime error
| import numpy as np | |
| from PIL import Image, ImageDraw, ImageFont, ImageFilter, ImageEnhance | |
| import cv2 | |
| from sklearn.cluster import KMeans | |
| import io | |
| import base64 | |
| class ImageProcessor: | |
| """Класс для обработки изображений""" | |
| def resize_to_standard(image, max_size=1024): | |
| """Изменяет размер изображения до стандартного""" | |
| ratio = min(max_size / image.width, max_size / image.height) | |
| if ratio < 1: | |
| new_size = (int(image.width * ratio), int(image.height * ratio)) | |
| return image.resize(new_size, Image.Resampling.LANCZOS) | |
| return image | |
| def create_before_after(before, after): | |
| """Создает сравнение до/после""" | |
| # Убедимся что изображения одного размера | |
| width = max(before.width, after.width) | |
| height = max(before.height, after.height) | |
| # Создаем новое изображение | |
| comparison = Image.new('RGB', (width * 2 + 20, height), (255, 255, 255)) | |
| # Вставляем изображения | |
| comparison.paste(before, (0, 0)) | |
| comparison.paste(after, (width + 20, 0)) | |
| # Добавляем подписи | |
| draw = ImageDraw.Draw(comparison) | |
| try: | |
| font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 30) | |
| except: | |
| font = None | |
| draw.text((width // 2 - 50, height - 50), "ДО", fill=(255, 255, 255), font=font, stroke_width=2, stroke_fill=(0, 0, 0)) | |
| draw.text((width + 20 + width // 2 - 70, height - 50), "ПОСЛЕ", fill=(255, 255, 255), font=font, stroke_width=2, stroke_fill=(0, 0, 0)) | |
| return comparison | |
| def create_grid(images, titles=None, cols=2): | |
| """Создает сетку из изображений""" | |
| if not images: | |
| return None | |
| n = len(images) | |
| rows = (n + cols - 1) // cols | |
| # Размер одного изображения | |
| img_width = images[0].width | |
| img_height = images[0].height | |
| # Создаем сетку | |
| grid_width = img_width * cols + 10 * (cols - 1) | |
| grid_height = img_height * rows + 10 * (rows - 1) + (50 if titles else 0) | |
| grid = Image.new('RGB', (grid_width, grid_height), (255, 255, 255)) | |
| draw = ImageDraw.Draw(grid) | |
| try: | |
| font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 20) | |
| except: | |
| font = None | |
| # Размещаем изображения | |
| for i, img in enumerate(images): | |
| row = i // cols | |
| col = i % cols | |
| x = col * (img_width + 10) | |
| y = row * (img_height + 10) + (50 if titles else 0) | |
| grid.paste(img, (x, y)) | |
| # Добавляем заголовок | |
| if titles and i < len(titles): | |
| draw.text((x + img_width // 2 - 50, y - 40), titles[i], fill=(0, 0, 0), font=font) | |
| return grid | |
| def detect_room_type(image): | |
| """Определяет тип комнаты по изображению""" | |
| # Упрощенная логика определения типа комнаты | |
| # В реальности здесь может быть ML модель | |
| # Конвертируем в numpy array | |
| img_array = np.array(image) | |
| # Анализируем цвета и формы | |
| # Это упрощенная эвристика | |
| avg_color = img_array.mean(axis=(0, 1)) | |
| # Простая логика на основе преобладающих цветов | |
| if avg_color[2] > avg_color[0] * 1.2: # Больше синего | |
| return "Ванная" | |
| elif avg_color[1] > avg_color[0] * 1.1: # Больше зеленого | |
| return "Детская" | |
| elif np.std(img_array) < 50: # Низкая контрастность | |
| return "Спальня" | |
| else: | |
| return "Гостиная" | |
| def apply_vignette(image, intensity=0.3): | |
| """Применяет эффект виньетки""" | |
| # Создаем маску виньетки | |
| width, height = image.size | |
| # Создаем радиальный градиент | |
| x = np.linspace(-1, 1, width) | |
| y = np.linspace(-1, 1, height) | |
| X, Y = np.meshgrid(x, y) | |
| radius = np.sqrt(X**2 + Y**2) | |
| # Создаем маску | |
| vignette = 1 - (radius * intensity) | |
| vignette = np.clip(vignette, 0, 1) | |
| vignette = (vignette * 255).astype(np.uint8) | |
| # Применяем к изображению | |
| vignette_img = Image.fromarray(vignette, mode='L') | |
| # Накладываем | |
| result = Image.new('RGB', image.size) | |
| result.paste(image, (0, 0)) | |
| result.paste((0, 0, 0), (0, 0), vignette_img) | |
| return Image.blend(image, result, intensity) | |
| class ColorPalette: | |
| """Класс для работы с цветовыми палитрами""" | |
| def extract_colors(image, n_colors=5): | |
| """Извлекает основные цвета из изображения""" | |
| # Уменьшаем изображение для ускорения | |
| small_image = image.resize((150, 150), Image.Resampling.LANCZOS) | |
| # Конвертируем в массив | |
| img_array = np.array(small_image) | |
| img_array = img_array.reshape(-1, 3) | |
| # Кластеризация цветов | |
| kmeans = KMeans(n_clusters=n_colors, random_state=42, n_init=10) | |
| kmeans.fit(img_array) | |
| # Получаем центры кластеров (основные цвета) | |
| colors = kmeans.cluster_centers_.astype(int) | |
| # Создаем изображение палитры | |
| palette_height = 100 | |
| palette_width = 500 | |
| color_block_width = palette_width // n_colors | |
| palette_img = Image.new('RGB', (palette_width, palette_height)) | |
| draw = ImageDraw.Draw(palette_img) | |
| for i, color in enumerate(colors): | |
| x_start = i * color_block_width | |
| x_end = (i + 1) * color_block_width | |
| color_tuple = tuple(color) | |
| draw.rectangle([x_start, 0, x_end, palette_height], fill=color_tuple) | |
| return palette_img, colors.tolist() | |
| def suggest_palette(style_name): | |
| """Предлагает цветовую палитру для стиля""" | |
| palettes = { | |
| "Современный минимализм": ["#FFFFFF", "#F5F5F5", "#E0E0E0", "#9E9E9E", "#424242"], | |
| "Скандинавский": ["#FFFFFF", "#F8F8F8", "#E8DCC6", "#A8A8A8", "#4A4A4A"], | |
| "Индустриальный": ["#2C2C2C", "#4A4A4A", "#7A7A7A", "#B8860B", "#8B4513"], | |
| "Бохо": ["#CD853F", "#DEB887", "#D2691E", "#8B4513", "#A0522D"], | |
| "Японский": ["#F5DEB3", "#D2B48C", "#BC8F8F", "#8B7355", "#4B4B4B"], | |
| "Ар-деко": ["#FFD700", "#B8860B", "#2F4F4F", "#000000", "#8B0000"], | |
| "Прованс": ["#E6E6FA", "#DDA0DD", "#D8BFD8", "#9370DB", "#8B7D6B"], | |
| "Хай-тек": ["#C0C0C0", "#808080", "#4169E1", "#000000", "#FFFFFF"] | |
| } | |
| return palettes.get(style_name, ["#FFFFFF", "#E0E0E0", "#808080", "#404040", "#000000"]) | |
| def apply_color_filter(image, color_rgb, intensity=0.3): | |
| """Применяет цветовой фильтр к изображению""" | |
| # Создаем цветной слой | |
| color_layer = Image.new('RGB', image.size, color_rgb) | |
| # Смешиваем с оригиналом | |
| return Image.blend(image, color_layer, intensity) | |
| def adjust_brightness_contrast(image, brightness=1.0, contrast=1.0): | |
| """Настройка яркости и контраста""" | |
| # Яркость | |
| enhancer = ImageEnhance.Brightness(image) | |
| image = enhancer.enhance(brightness) | |
| # Контраст | |
| enhancer = ImageEnhance.Contrast(image) | |
| image = enhancer.enhance(contrast) | |
| return image | |