首页 > 解决方案 > Discord.py 错误,PIL.UnidentifiedImageError: 无法识别图像文件

问题描述

我正在制作一个不和谐的机器人,只要有人更改他们的头像,它就会发送一条消息。它下载他们以前的头像和新头像,并将它们连接在一起,但我收到此错误:

Ignoring exception in on_user_update
Traceback (most recent call last):
File "/app/.heroku/python/lib/python3.6/site-packages/discord/client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "bot.py", line 40, in on_user_update
images = [Image.open(x) for x in ['originalAvatar.png', 'updatedAvatar.png']]
File "bot.py", line 40, in <listcomp>
images = [Image.open(x) for x in ['originalAvatar.png', 'updatedAvatar.png']]
File "/app/.heroku/python/lib/python3.6/site-packages/PIL/Image.py", line 2959, in open
"cannot identify image file %r" % (filename if filename else fp)
PIL.UnidentifiedImageError: cannot identify image file 'originalAvatar.png'

这是我的代码:

@bot.event
async def on_user_update(before, after):
if before.avatar != after.avatar:
    mencao = after.mention
    channel = bot.get_channel(zzzzzzzzzzzzz)
    authorId = after.id
    tempo = datetime.date.today().strftime("%d/%m/%Y")

    originalFile = before.avatar_url_as(format='png', static_format='webp', size=128)
    updatedFile = after.avatar_url_as(format='png', static_format='webp', size=128)

    r = requests.get(originalFile, allow_redirects=True)
    open('originalAvatar.png', 'wb').write(r.content)
    s = requests.get(updatedFile, allow_redirects=True)
    open('updatedAvatar.png', 'wb').write(s.content)

    images = [Image.open(x) for x in ['originalAvatar.png', 'updatedAvatar.png']]
    widths, heights = zip(*(i.size for i in images))

    total_width = sum(widths)
    max_height = max(heights)

    new_im = Image.new('RGB', (total_width, max_height))

    x_offset = 0
    for im in images:
        new_im.paste(im, (x_offset, 0))
        x_offset += im.size[0]

    new_im.save('test.png')

    file = discord.File("test.png", filename="image.png")
    embed = discord.Embed(name="title", description=f"\U0001F5BC {mencao} **alterou o avatar**", color=0xe12674)
    embed.set_image(url="attachment://image.png")
    embed.set_footer(text=f"ID do usuário: {authorId} • {tempo}")

    await channel.send(file=file, embed=embed)

    if os.path.exists(f"originalAvatar.png"):
        os.remove(f"originalAvatar.png")
    if os.path.exists(f"updatedAvatar.png"):
        os.remove(f"updatedAvatar.png")
    if os.path.exists("test.png"):
        os.remove("test.png")

我在heroku btw上运行python文件,我该如何解决这个问题?

更新:我已经替换 open('originalAvatar.png', 'wb').write(r.content)

 with open('originalAvatar.png', 'wb').write(r.content) as f:
            r.raw.decode_content = True
            shutil.copyfileobj(r.raw, f)

但现在它给了我这个错误:

Ignoring exception in on_user_update
Traceback (most recent call last):
File "/home/lucas/.local/lib/python3.8/site-packages/discord/client.py", line 
343, in _run_event
await coro(*args, **kwargs)
File "/home/lucas/bot/bot.py", line 36, in on_user_update
with open('originalAvatar.png', 'wb').write(r.content) as f:
AttributeError: __enter__

这是on_message代码的一部分:

 @bot.event
 async def on_message(message):
 mensagem = message.content
 if mensagem.startswith("$avatar") and hasNumbers(mensagem) == False:
     nome = message.author.name
     avatar = message.author.avatar_url_as(size=2048)
     r = requests.get(avatar, allow_redirects=True)
     with open('Avatar.gif', 'wb').write(r.content) as f:
         r.raw.decode_content = True
         shutil.copyfileobj(r.raw, f)

标签: pythonherokudiscord.pypython-imaging-library

解决方案


以下行有几个问题:

r = requests.get(originalFile, allow_redirects=True)
open('originalAvatar.png', 'wb').write(r.content)

一方面,它不会关闭文件originalAvatar.pngwith open应使用该语句来避免此问题。其次,它没有将图像的实际原始二进制数据正确写入文件。有多种方法可以做到这一点(见这里),所以我将只展示一种可能的方法,基于这个问题

r = requests.get(originalFile, allow_redirects=True)
r.raw.decode_content = True
with f = open('originalAvatar.png', 'wb'):
    shutil.copyfileobj(r.raw, f)

推荐阅读