游乐游手机版
首页/编程语言/文章详情

Python自动化生成带装饰图形渐变背景文字封面

时间:2026-07-22 20:09
基于Python的Pillow库实现封面自动生成,包含水平渐变背景、半透明装饰图形(圆环、三角形)、半透明遮罩层及文字层,支持主副标题及自定义比例,输出PNG格式图片。

一、背景介绍

在撰写博客时,封面图始终是绕不开的环节。专栏封面要求1:1比例,文章封面推荐16:9,而网上搜到的图片大多比例不匹配,不得不手动进入Photoshop或Illustrator裁剪、添加文字。反复操作导致大量重复劳动,因此决定用Python自动化解决。为简化实现,封面背景不直接使用图片,改用渐变填充,并在左下角与右上角添加半透明装饰图形,避免封面过于单调,保留一定设计感。

二、功能介绍

效果预览

Python自动化生成带装饰图形的渐变背景文字封面

功能清单

内置4种渐变背景,用户可根据需要轻松扩充。

内置4种边缘装饰图形:圆环、三角形、正方形、六边形。

文字支持两种排版方案:

  • 仅显示主标题,居中展示
  • 主标题加副标题,副标题宽度不超过主标题,中间有一条半透明分割线

三、过程拆解

整个实现过程可拆解为四个核心步骤,下面逐一讲解。

Python自动化生成带装饰图形的渐变背景文字封面

先创建一个封装类 BlogCoverGenerator,在 __init__ 方法中定义所需属性,再编写生成封面的核心方法。注意:后续许多操作涉及透明度,因此基础图形的 mode 需设为 RGBA,生成的图片也必须是 PNG 格式。

class BlogCoverGenerator:
    def __init__(self,
                 title: str,
                 sub_title: str,
                 title_h_ratio: float=.5,
                 ratio_pair: tuple[int]=(16, 9),
                 bg_gradient: BackgroundGradient=BackgroundGradient.skyline,
                 bg_shape: BackgroundShape=BackgroundShape.circle,
                 min_size='1M'):
        # 封面主标题
        self.title = title
        # 封面副标题
        self.sub_title = sub_title
        # 如果没有副标题,主标题需要垂直居中
        self.no_sub_title = False
        if self.sub_title is None or '' == self.sub_title.strip():
            self.no_sub_title = True
        # 标题区域垂直方向占比(从正中心开始计算),参考值0.3~0.6
        self.title_h_ratio = title_h_ratio
        if self.title_h_ratio < 0.3:
            self.title_h_ratio = 0.3
        elif self.title_h_ratio > 0.6:
            self.title_h_ratio = 0.6
        # 字体位置
        self.zh_font_location = ''
        self.en_font_location = ''
        # 封面宽高比,16:9, 4:3, 1:1等,以16:9为例,需要传入(16, 9)
        self.ratio_pair = ratio_pair
        # 封面渐变背景色
        self.bg_gradient = bg_gradient
        # 封面背景几何图形,目前支持三角形、六边形、圆形
        self.bg_shape = bg_shape
        # 封面大小。如果传入字符串,支持的单位为k, M;也可以传入数值
        self.min_size = self._parse_min_size(min_size)
        if self.min_size > 178956970:
            # ImageDraw.text大小限制
            self.min_size = 178956970

    def generate_cover(self, output_path: str, output_file_name: str):
        width, height = self._get_cover_size()
        img = Image.new('RGBA', (width, height))

        # 第1层,渐变背景
        self._display_gradient_bg(img)
        # 第2层,边缘装饰图形
        img = self._display_decorate_shape(img)
        # 第3层,半透明遮罩
        img = self._display_transparent_mask(img)
        # 第4层,文字
        img = self._display_title(img)
        # 保存
        img.sa ve(os.path.join(output_path, output_file_name))

1. 渐变背景层

先定义一个渐变枚举,列出几种配色方案。

from enum import Enum
class BackgroundGradient(Enum):
    skyline = ['#1488CC', '#2B32B2']
    cool_brown = ['#603813', '#b29f94']
    rose_water = ['#E55D87', '#5FC3E4']
    crystal_clear = ['#159957', '#155799']

Pillow 官方文档并未提供直接绘制渐变的方法,此处仅实现水平方向渐变。核心思路:在起始颜色与结束颜色之间按宽度计算步长,通过循环逐行绘制不同颜色的垂直线条。代码如下:

class BlogCoverGenerator:
    def _display_gradient_bg(self, base_img: Image):
        img_w, img_h = base_img.size
        draw = ImageDraw.Draw(base_img)
        start_color, end_color = self.bg_gradient.value
        if '#' in start_color:
            start_color = ImageColor.getrgb(start_color)
        if '#' in end_color:
            end_color = ImageColor.getrgb(end_color)

        # 水平方向渐变,渐变步长
        step_r = (end_color[0] - start_color[0]) / img_w
        step_g = (end_color[1] - start_color[1]) / img_w
        step_b = (end_color[2] - start_color[2]) / img_w

        for i in range(0, img_w):
            bg_r = round(start_color[0] + step_r * i)
            bg_g = round(start_color[1] + step_g * i)
            bg_b = round(start_color[2] + step_b * i)
            draw.line([(i, 0), (i, img_h)], fill=(bg_r, bg_g, bg_b))

这一步的效果图如下:

Python自动化生成带装饰图形的渐变背景文字封面

2. 装饰图形层

实现代码较多,此处重点讲解思路。

先定义一个装饰图形枚举:

from enum import Enum
class BackgroundShape(Enum):
    circle = 1
    triangle = 2
    square = 3
    hexagon = 4

装饰图形需要具备透明度,因此使用 Image.alpha_composite() 将半透明图形混合到渐变背景上。

文字区域是核心,装饰图形不能遮挡它。文字区域的控制参数为 title_h_ratio

Pillow 的 ImageDraw 类提供了 regular_polygon() 方法用于绘制正多边形,但遗憾的是不支持设置轮廓宽度(默认值为1)。而我们需要指定轮廓宽度。若使用 polygon() 自行计算顶点坐标,遇到旋转多边形时非常繁琐。因此采用一种变通办法:

BlogCoverGenerator
    @staticmethod
    def _width_regular_polygon(draw: ImageDraw, width: int,
                               bounding_circle, n_sides, rotation=0, fill=None, outline=None):
        """
        pillow提供的regular_polygon,不支持对outline设置width,自定义方法,支持轮廓宽度
        """
        start = bounding_circle[2]
        for i in np.arange(0, width, 0.05):
            new_bounding_circle = (bounding_circle[0], bounding_circle[1], start + i)
            draw.regular_polygon(bounding_circle=new_bounding_circle, n_sides=n_sides,
                                 rotation=rotation, fill=fill, outline=outline)

这里的 bounding_circle 是元组 (x, y, r),表示多边形的外切圆,包含圆心坐标和半径。画圆环时使用的 ImageDraw.ellipse() 需要左上角和右下角坐标,可转换为 bounding_circle 形式,从而复用位置参数。

这一步的效果图(以圆环为例):

Python自动化生成带装饰图形的渐变背景文字封面

3. 半透明遮罩层

这一步实现非常简单,直接参考代码:

class BlogCoverGenerator:
    @staticmethod
    def _display_transparent_mask(base_img: Image):
        img_w, img_h = base_img.size
        img_mask = Image.new('RGBA', (img_w, img_h), color=(0, 0, 0, 135))
        return Image.alpha_composite(base_img, img_mask)

4. 文字层

这里有两个关键点。第一,需根据标题文字判断是中文还是英文,并选择对应字体。

class BlogCoverGenerator:
    def _get_real_font(self, target_title: str, font_size: int):
        for ch in target_title:
            if u'u4e00' <= ch <= u'u9fff':
                # 中文字体
                return ImageFont.truetype(self.zh_font_location, font_size)
        # 英文字体
        return ImageFont.truetype(self.en_font_location, font_size)

    def set_fonts(self, zh_font_location: str, en_font_location: str):
        self.zh_font_location = zh_font_location
        self.en_font_location = en_font_location

第二,字体大小需要动态调整。这里采用预渲染并检查字体宽度的方法,借助 ImageFont.getbbox()

class BlogCoverGenerator:
    def _display_title(self, base_img: Image):
        def get_checked_font_size(target_title: str, font_size: int, max_width: int):
            # 预检查,判断文字宽度是否超出封面
            check_font = self._get_real_font(target_title, font_size)
            _, _, check_w, check_h = check_font.getbbox(target_title)
            if check_w > max_width:
                scale_ratio = max_width / check_w
                font_size = int(font_size * scale_ratio)
            return font_size

最终效果图如下:

Python自动化生成带装饰图形的渐变背景文字封面

以上就是使用 Python 自动生成带装饰图形的渐变背景文字封面的完整实现。思路清晰,代码易于扩展,感兴趣的朋友可以直接拿去使用。

来源:https://www.jb51.net/python/367843z8x.htm
上一篇Python3注释编写完全指南:从基础规范到高效实践 下一篇Ubuntu系统中Golang编译时如何启用缓存加速提高效率
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
FileZilla断点续传设置与操作指南
编程语言 · 2026-07-25

FileZilla断点续传设置与操作指南

FileZilla支持断点续传,需客户端与服务器均开启REST命令。设置中确保启用断点续传及继续传输选项。中断后自动或手动从断点恢复。注意服务器支持、传输模式匹配及文件完整性校验。

Debian系统C++编译器位置查找方法
编程语言 · 2026-07-25

Debian系统C++编译器位置查找方法

在Debian系统中,通过apt安装的C++编译器g++默认位于 usr bin g++,可使用which或whereis命令验证路径。g++属于build-essential软件包,若未安装则需执行sudoaptinstallbuild-essential。该包还包含gcc、make等编译工具链,g++是GNUC++编译器,实际是符号链接指向具体版本,验证

Debian系统安装C++环境的方法
编程语言 · 2026-07-25

Debian系统安装C++环境的方法

在Debian系统安装C++开发环境:先sudoaptupdate更新包列表,再sudoaptinstallbuild-essential安装编译工具链,或单独安装g++。用g++--version验证。可选安装VSCode、GDB、CMake等工具并配置默认编译器版本。

Debian系统C++开发环境配置指南
编程语言 · 2026-07-25

Debian系统C++开发环境配置指南

在Debian系统中,先执行aptupdate更新软件包列表,再安装build-essential元包即可获得GCC、G++、Make和GDB。通过运行g++--version命令验证编译器安装成功。可选安装VisualStudioCode、CLion等编辑器及CMake构建工具,并编写一个简单的HelloWorld程序,使用g++编译运行以验证环境配置正确

通过cpustat工具查看CPU状态的具体方法与详细步骤
编程语言 · 2026-07-25

通过cpustat工具查看CPU状态的具体方法与详细步骤

cpustat是sysstat包中的CPU监控工具,可按固定间隔输出带时间戳的CPU使用率统计。安装后运行cpustat即可实时显示各核心信息,常用指标包括%usr、%sys、%iowait、%steal和%idle,用于定位用户态、内核态或I O瓶颈。高级选项-c可显示单核统计,-m可同时查看内存使用,适合脚本采集和性能分析。