avtopost.kultmost.ru/images.py

67 lines
2.0 KiB
Python

from io import BytesIO
from PIL import Image, ImageDraw, ImageFilter
Image.MAX_IMAGE_PIXELS = 50_000_000
def insert_logo(
background,
logo,
scale_factor=0.095,
padding=8,
radius=15,
quality=95
):
background = background.copy().convert("RGBA")
# Логотип
logo = logo.copy().convert("RGBA")
# Масштабирование
logo_w, logo_h = logo.size
back_w, back_h = background.size
new_w = max(1, int(back_w * scale_factor))
ratio = logo_w / logo_h if logo_h > 0 else 1
new_h = max(1, int(new_w / ratio))
logo = logo.resize((new_w, new_h), Image.Resampling.LANCZOS)
# === Создаём полностью прозрачный фон ===
transparent = Image.new("RGBA", (new_w, new_h), (0, 0, 0, 0))
# Компонуем логотип на полностью прозрачный фон (убирает все артефакты)
logo = Image.alpha_composite(transparent, logo)
# === Маска закругления ===
mask = Image.new("L", (new_w, new_h), 0)
draw = ImageDraw.Draw(mask)
draw.rounded_rectangle([(0, 0), (new_w-1, new_h-1)], radius=radius, fill=255)
mask = mask.filter(ImageFilter.SMOOTH)
# Применяем маску через composite (самый чистый способ)
logo = Image.composite(logo, transparent, mask)
# Позиция (нижний левый угол)
pos_x = padding
pos_y = back_h - new_h - padding
if pos_y < 0:
pos_y = 0
# Вставка
background.paste(logo, (pos_x, pos_y), logo)
# Сохранение
out = BytesIO()
background.convert("RGB").save(out, format="JPEG", quality=quality, optimize=True)
out.seek(0)
return out
async def convert_bio_to_webp(bio: BytesIO, quality: int = 95) -> BytesIO:
bio.seek(0)
im = Image.open(bio).convert("RGB")
out = BytesIO()
im.save(out, format="WEBP", quality=quality, method=6)
out.seek(0)
return out