discord.py调用Pillow绘图传int值触发TypeError问题排查
问题描述
- 开发场景:基于discord.py框架开发Discord机器人
crafting合成计算指令,预期执行逻辑为:- 接收用户传入的整数参数
num - 按固定比例计算合成所需的
copper_rod、steel_bolt、steel_plate数量 - 调用Pillow库将计算得到的数值绘制到预设素材图片上
- 将生成的结果图片发送到当前频道
- 接收用户传入的整数参数
- 异常表现:传入整数参数调用指令时直接抛出如下错误,无法完成图片绘制和消息发送
Ignoring exception in command crafting: Traceback (most recent call last): File "/home/runner/lmcbot/venv/lib/python3.8/site-packages/discord/ext/commands/core.py", line 85, in wrapped ret = await coro(*args, **kwargs) File "main.py", line 380, in crafting draw.text((355,565), copper_rod, (37, 35, 32), font=font) File "/home/runner/lmcbot/venv/lib/python3.8/site-packages/PIL/ImageDraw.py", line 373, in text if self._multiline_check(text): File "/home/runner/lmcbot/venv/lib/python3.8/site-packages/PIL/ImageDraw.py", line 348, in _multiline_check return split_character in text TypeError: argument of type 'int' is not iterable The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/home/runner/lmcbot/venv/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 939, in invoke await ctx.command.invoke(ctx) File "/home/runner/lmcbot/venv/lib/python3.8/site-packages/discord/ext/commands/core.py", line 863, in invoke await injected(*ctx.args, **ctx.kwargs) File "/home/runner/lmcbot/venv/lib/python3.8/site-packages/discord/ext/commands/core.py", line 94, in wrapped raise CommandInvokeError(exc) from exc discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: argument of type 'int' is not iterable
- 原问题代码:
@client.command() async def crafting(ctx, num: int): img = Image.open("gearboxcrafting.png") font = ImageFont.truetype("Bold-X3RG.ttf", 30) copper_rod = num * 10 steel_bolt = num * 50 steel_plate = num * 25 draw = ImageDraw.Draw(img) draw.text((355,565), copper_rod, (37, 35, 32), font=font) draw.text((355,656), steel_bolt, (37, 35, 32), font=font) draw.text((355,747), steel_plate, (37, 35, 32), font=font) img.save("test.png") await ctx.send(file = discord.File("test.png"))
根因分析
Pillow的ImageDraw.text方法要求待绘制的文本参数必须为字符串类型。当前代码中通过乘法计算得到的copper_rod、steel_bolt、steel_plate三个变量均为整数类型,方法内部执行换行符检测逻辑时,会判断换行符是否存在于传入的文本参数中,而整数属于不可迭代类型,无法执行成员判断操作,因此触发类型错误。
修复方法
调用draw.text时,将传入的三个整数变量通过str()方法转为字符串即可,修复后的完整代码如下:
@client.command() async def crafting(ctx, num: int): img = Image.open("gearboxcrafting.png") font = ImageFont.truetype("Bold-X3RG.ttf", 30) copper_rod = num * 10 steel_bolt = num * 50 steel_plate = num * 25 draw = ImageDraw.Draw(img) # 传入绘制方法前将整数转为字符串类型 draw.text((355,565), str(copper_rod), (37, 35, 32), font=font) draw.text((355,656), str(steel_bolt), (37, 35, 32), font=font) draw.text((355,747), str(steel_plate), (37, 35, 32), font=font) img.save("test.png") await ctx.send(file = discord.File("test.png"))
内容的提问来源于stack exchange,提问作者Game Programmer
相关产品推荐
相关产品推荐

