89 lines
2.4 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
布局抽象基类
"""
from abc import ABC, abstractmethod
from typing import Tuple, Optional
from PIL import Image, ImageDraw
from ..schemas.content import PosterContent
from ..schemas.theme import Theme
from ..renderers.text import TextRenderer
from ..renderers.shape import ShapeRenderer
from ..renderers.effect import EffectRenderer
class BaseLayout(ABC):
"""
所有布局的抽象基类
布局负责:
1. 计算内容区域位置和尺寸
2. 协调各渲染器绘制内容
3. 生成最终海报图像
"""
# 默认尺寸 (小红书 3:4)
DEFAULT_SIZE = (1080, 1440)
# 默认边距
MARGIN = 48
PADDING = 32
def __init__(self, size: Tuple[int, int] = None):
self.width, self.height = size or self.DEFAULT_SIZE
self.size = (self.width, self.height)
# 渲染器
self.text = TextRenderer()
self.shape = ShapeRenderer()
self.effect = EffectRenderer()
@abstractmethod
def generate(self, content: PosterContent, theme: Theme) -> Image.Image:
"""
生成海报
Args:
content: 海报内容
theme: 主题配置
Returns:
生成的海报图像
"""
pass
@abstractmethod
def calculate_content_height(self, content: PosterContent, theme: Theme) -> int:
"""
计算内容区域高度 (用于动态适配)
Args:
content: 海报内容
theme: 主题配置
Returns:
内容区域高度
"""
pass
def create_canvas(self, background: Tuple[int, int, int] = (255, 255, 255)) -> Image.Image:
"""创建画布"""
return Image.new("RGBA", self.size, (*background, 255))
def create_gradient_background(self, theme: Theme) -> Image.Image:
"""创建渐变背景"""
colors = theme.gradient_rgb
return self.effect.create_gradient(self.size, colors[0], colors[1])
def paste_with_alpha(self, canvas: Image.Image, layer: Image.Image, pos: Tuple[int, int]):
"""粘贴带透明度的图层"""
canvas.paste(layer, pos, layer)
@property
def layout_name(self) -> str:
"""布局名称"""
return self.__class__.__name__.replace("Layout", "").lower()