【小白学Python】自定义图片的生成(二)

Python学习
【小白学Python】自定义图片的生成(一)

1. 文件内容

正如上篇文章所说,我需要读取txt文件的文字内容,将文字内容填充到图片上,按照一定规则生成多个图片。
文件大致内容如下
在这里插入图片描述

2.生成图片规则

txt是之前从zhihu问答模块尝试爬取的,可以看出来,上述文字是以问答形式呈现的,生成图片规则有两个:

  1. 每个QA的文字单独一张图片Q一行,A一行
  2. 去掉**@之后,:**之前的文字。

3. 修改代码

上一篇的完整代码如下

from PIL import Image, ImageDraw, ImageFont

# 设置图片大小
width, height = 800, 800
image = Image.new('RGB', (width, height), color='black')

# 设置文字
text = "123456"

# 加载字体文件,并设置字体大小
# 注意:确保arial.ttf字体文件路径是正确的
font = ImageFont.truetype('C:\\Windows\\Fonts\\arial.ttf', 60)
# font.color = 'yellow'
# 创建画布
draw = ImageDraw.Draw(image)

# 使用draw的textsize方法获取文本大小
text_width, text_height = draw.textsize(text, font=font)

# 计算文字位置,使其居中
x = (width - text_width) / 2
y = (height - text_height) / 2

# 绘制文字
draw.text((x, y), text, font=font, fill='white')

# 保存图片
image.save('text_image.png')

2.1 尝试一行汉字展示

替换代码如下
在这里插入图片描述
执行main.py,查看生成的图片,有问题,乱码了。
在这里插入图片描述

搜索后发现是字体使用的不兼容,更换字体为simhei.ttf,图片文字正常展示。
调整图片长宽为 width, height = 600, 900,文字位置为

x = (width - text_width) / 2
y = (height - text_height) / 3.5

执行main.py,目前看起来运作一切良好。
在这里插入图片描述

3.1 读取txt文件

为了读取指定的txt文件,我们对上述代码做了如下改动

  • 使用file.readlines()一次性读入所有txt内容,大文件需要注意,内存可能会爆
  • 根据文件内容,每4行拼接一次text,并生成一个图片
  • 将生成图片的逻辑拆分,新增drawText(text函数
from PIL import Image, ImageDraw, ImageFont

# 打开txt文件,将txt文件内容读入内存
# !!!如果文件过大,最好不要直接这么写
with open('QA.txt', 'r', encoding='utf-8') as file:
    lines = file.readlines()

text = ''

def drawText(text):
    # 设置图片大小
    width, height = 600, 900
    image = Image.new('RGB', (width, height), color='black')
    # 加载字体文件,并设置字体大小
    # 注意:确保arial.ttf字体文件路径是正确的
    font = ImageFont.truetype('C:\\Windows\\Fonts\\simhei.ttf', 20)
    # font.color = 'yellow'
    # 创建画布
    draw = ImageDraw.Draw(image)
    # 使用draw的textsize方法获取文本大小
    text_width, text_height = draw.textsize(text, font=font)
    if text_width > width + 10:
        font.size = font.size - 1
    # 计算文字位置,使其居中
    x = (width - text_width) / 2
    y = (height - text_height) / 3.5
    # 绘制文字
    draw.text((x, y), text, font=font, fill='white')
    # 保存图片
    image.save('pics/text_image_' + index.__str__() + '.png')

for index in range(len(lines)):

    #根据txt文件内容 每4行生成一张图片

    if index == 0 or index % 4 != 0:
        text = text + lines[index]
        #如果是txt结尾了,直接生成图片
        if index + 1 == len(lines):
            drawText(text)
    else:
        text = text + lines[index]
        drawText(text)
        # 将拼接的字符初始化
        text = ''

上述生成的逻辑满足了每个QA都是单独的图片,但是如果QA文字过多的话,图片中的文字会超过图片边界,无法正常展示
在这里插入图片描述

3.2 解决文字过长问题

draw.text绘制文字的函数并没有设置自动换行的功能,貌似只能根据图片的width来计算文字的长度,再尝试换行。

在这里插入图片描述
经过简单调试,采用往字符串中添加换行符\n的形式,这样图片绘制文字时可自动换行。
我这里处理的比较简单,固定的添加位置,很长的文字也只换行一次,但目前我的txt文件暂时可以用这种方式。

在这里插入图片描述

3.3 删减指定文字

由于txt文件是从zhihu爬取的,回答的时候会带上作者的名字,我想把这些文字去掉

在这里插入图片描述
在这里插入图片描述
新增如下删减函数

def remove_between_chars(s, start, end):
    while True:
        start_index = s.find(start)
        if start_index == -1:
            break
        end_index = s.find(end, start_index + len(start))
        if end_index == -1:
            break
        s = s[:start_index] + s[end_index + len(end):]
    return s

在这里插入图片描述
在这里插入图片描述

4. 总结

我的目标是将txt文件中的文字,按照一定规则绘制在图片上,当前的实现效果马马虎虎。

暂时的完整代码如下:

from PIL import Image, ImageDraw, ImageFont

# 打开txt文件,将txt文件内容读入内存
# !!!如果文件过大,最好不要直接这么写
with open('QA.txt', 'r', encoding='utf-8') as file:
    lines = file.readlines()

text = ''


def remove_between_chars(s, start, end):
    while True:
        start_index = s.find(start)
        if start_index == -1:
            break
        end_index = s.find(end, start_index + len(start))
        if end_index == -1:
            break
        s = s[:start_index] + s[end_index + len(end):]
    return s


def draw_text(text):
    text = remove_between_chars(text, '@', ':')
    # 设置图片大小
    width, height = 600, 900
    image = Image.new('RGB', (width, height), color='black')
    # 加载字体文件,并设置字体大小
    # 注意:确保arial.ttf字体文件路径是正确的
    font = ImageFont.truetype('C:\\Windows\\Fonts\\simhei.ttf', 20)
    # font.color = 'yellow'
    # 创建画布
    draw = ImageDraw.Draw(image)
    # 使用draw的textsize方法获取文本大小
    text_width, text_height = draw.textsize(text, font=font)
    # 计算文字位置,使其居中
    x = (width - text_width) / 2
    y = (height - text_height) / 3.5

    # 此处简单处理 如果将要到达边界,往字符串指定位置增加换行符
    # 这里经过调试,我这里使用22比较合适,后续需要优化
    if text_width > width - 10:
        new_text = text[:22] + "\n\n     " + text[22:]
        # 绘制文字
        x = (width - text_width // 2) / 2.5
        draw.text((x, y), new_text, font=font, fill='white')
    else:
        # 绘制文字
        draw.text((x, y), text, font=font, fill='white')
    # 保存图片
    image.save('pics/text_image_' + index.__str__() + '.png')


for index in range(len(lines)):
    # 根据txt文件内容 每4行生成一张图片
    if index == 0 or index % 4 != 0:
        text = text + lines[index]
        # 如果是txt结尾了,直接生成图片
        if index + 1 == len(lines):
            draw_text(text)
    else:
        text = text + lines[index]
        draw_text(text)
        # 将拼接的字符初始化
        text = ''

我对python掌握的比较浅显,编写代码还不太流畅,要花费不少时间用来补充基础知识,代码有很多优化是必要,上述代码的书写毫无美感可言,无论是逻辑还是简单的规范,都有很大提升的必要。

下一步的计划,除了学习python和优化代码之外,将爬取txt文件的功能和图片生成的功能结合起来,自动爬取自动生成,再长远点自动发布到指定平台

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值