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

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

目录

    • 1. 文件内容
    • 2.生成图片规则
    • 3. 修改代码
      • 2.1 尝试一行汉字展示
      • 3.1 读取txt文件
      • 3.2 解决文字过长问题
      • 3.3 删减指定文字
    • 4. 总结

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文件的功能和图片生成的功能结合起来,自动爬取自动生成,再长远点自动发布到指定平台

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/705298.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

KUKA机器人KRC5控制柜面板LED显示

对于KUKA机器人新系列控制柜KRC5控制柜来说,其控制柜面板LED布局如下图: 其中①②③④分别为: 1、机器人控制柜处于不同状态时,LED显示如下: 2、机器人控制柜正在运行时: 3、机器人控制柜运行时出现的故障…

数据结构重要知识总结

数组 数组(Array) 是一种很常见的数据结构。它由相同类型的元素(element)组成,并且是使用一块连续的内存来存储。 我们直接可以利用元素的索引(index)可以计算出该元素对应的存储地址。 数组…

【C++】stack、queue模拟实现

💗个人主页💗 ⭐个人专栏——C学习⭐ 💫点击关注🤩一起学习C语言💯💫 目录 导读 1. stack和queue的底层 1.1 stack 1.2 queue 2. 什么是适配器 3. 常见适配器 4. stack具体实现 4.1 成员变量 4.2 …

wms海外仓系统有哪些?选择的时候怎么避坑

虽然说wms海外仓系统能够在很大程度上提升海外仓的经营效率,但是如果在选择wms海外仓系统的时候没有慎重考虑,也是非常容易踩坑的。 这样不只是不能提升自己海外仓的效率,反倒是浪费了大量的预算和精力,这就得不偿失了。今天我们…

【Three.js】知识梳理二十三:Three.js与其他WebGL库与框架对比

在WebGL开发中,Three.js是一个非常流行的库,它简化了3D图形的创建和渲染过程。然而,市场上还有许多其他的WebGL库,如 Babylon.js、PlayCanvas、PIXI.js 和 Cesium,它们也有各自的特点和优势。本文将对Three.js 与这些常…

早知 121私人导航升级新版本, 第一次使用原生dialog标签。

早知121项目介绍说明 早知121 - 一个快速创建私人导航网站。 用途: 创建个人的工作导航,收集常用网址,可贡献给同事。创建个人垂直领域导航 优点: - 不需懂技术,不用维护服务器,维护私人导航收藏站。 网…

贝壳找房: 为 AI 平台打造混合多云的存储加速底座

贝壳机器学习平台的计算资源,尤其是 GPU,主要依赖公有云服务,并分布在不同的地理区域。为了让存储可以灵活地跟随计算资源,存储系统需具备高度的灵活性,支持跨区域的数据访问和迁移,同时确保计算任务的连续…

2024网络安全学习路线 非常详细 推荐学习

关键词:网络安全入门、渗透测试学习、零基础学安全、网络安全学习路线 首先咱们聊聊,学习网络安全方向通常会有哪些问题 1、打基础时间太长 学基础花费很长时间,光语言都有几门,有些人会倒在学习 linux 系统及命令的路上&#…

ROC曲线和AUC,推荐系统中常用AUC作为排序模型的评估指标

文章目录 1、ROC曲线2、AUC计算及代码 1、ROC曲线 在不同的应用任务中,我们可根据任务需求来采用不同的截断点。如果我们更重视“查准率”,则可选择排序中靠前的位置进行截断;如果更重视“查全率”,则可选择靠后的位置进行截断。…

C++怎么根据变量名称返回变量的值?

在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「C的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!! 有点好奇你这么做是为了什么。…

184.二叉树:二叉树的最近公共祖先(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:// 函数用于寻找二叉树中节点 p 和 q 的最低公…

聚类性能度量

在机器学习中,聚类是一种无监督学习,那对于聚类结果,我们应该如何评估其好坏呢?我们这里介绍两类性能度量。 1.外部指标 外部指标的意思是将聚类结果与某个“参考模型”进行比较。哎其实也很好理解,就相当于老师批改卷…

AGI时代引领未来,大模型重塑市场发展

前言 在数字化浪潮席卷全球的今天,人工智能(AI)技术正以前所未有的速度推动着各行各业的变革。其中,大模型作为AI领域的重要分支,正以其独特的优势,为程序员和企业产品经理这两大核心群体开辟出崭新的发展…

# RocketMQ 实战:模拟电商网站场景综合案例(十)

RocketMQ 实战:模拟电商网站场景综合案例(十) 一、RocketMQ 实战:模拟电商网站场景综合案例-- 创建支付订单流程 1、支付订单流程 2、在 shop-pay-service 工程模块中,创建 启动 类 PayServiceApplication.java /***…

MT7981B+MT7976C+MT7531A RF定频测试方法

1、从下面网址下载QA软件包,然后在WIN系统下安装QA环境。 https://download.csdn.net/download/zhouwu_linux/89428691?spm1001.2014.3001.5501 在WINDOWS 7系统下先安装WinPcap_4_1_3.exe。 2、搭建硬件环境,电脑先连接仪器,主板网络与电…

天地图开发实战:Vue结合OpenLayers实现动态点位地图

在Web开发中,地图功能是一个常见的需求,尤其是在需要展示地理位置信息的应用程序中。OpenLayers(简称OL)是一个强大的JavaScript库,用于创建交互式地图。本文将介绍如何利用OpenLayers和天地图API,实现一个…

Mybatis save、saveOrUpdate、update的区别

哈喽,大家好,我是木头左! 1. save方法 Mybatis的save方法用于插入一条新的记录。当数据库中不存在相同的记录时,会执行插入操作;如果已经存在相同的记录,则会抛出异常。 int result sqlSession.insert(&…

电脑桌面提醒做事的app 好用的桌面提醒app

在快节奏的现代生活中,我们每天都要通过电脑处理大量的工作事项。然而,繁忙的工作节奏有时会导致我们遗忘某些重要任务,从而带来不必要的损失。为了避免这种情况,选择一款好用的桌面提醒app显得尤为重要。 想象一下,你…

Java中Transactional在不同方法间的穿透性,rollbackFor参数含义

哈喽,大家好,我是木头左! 在Java开发中,经常会遇到需要在一个事务中执行多个操作的场景。为了确保这些操作的原子性,可以使用Spring框架提供的Transactional注解来实现事务管理。然而,在实际开发过程中&…

CVE-2012-2122-mysql未授权访问漏洞复现-vulhub

1.原理 参考:CVE-2012-2122 Mysql身份认证漏洞及利用-CSDN博客 简单来说,除了配置上的问题以外,是密码的验证出现了漏洞,导致尝试次数多了之后直接可以登入 使用:kalivulhub 2.复现 开一下镜像,用的是v…