You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:39:44