我如何编写一个不和谐的机器人,使其能够使用 python PIL post 修改 gif and/or png 个人资料图片?

How do I code a discord bot so it becomes able to post modified gif and/or png profile picture using python PIL?

此代码适用于个人资料图片中具有 .png 格式的用户,但是,当涉及到具有 .gif 动画个人资料图片的用户时,该代码不起作用。它给出了这个错误 OSError(f"cannot write mode {mode} as PNG") from e OSError: cannot write mode PA as PNG

我试图将所有 .png 更改为 .gif,但我仍然遇到问题。

ValueError: image has wrong mode

这是上述代码,仅适用于 .png 格式。

class avatar(commands.Cog):
    def __init__(self, client):
        self.client = client

    @commands.Cog.listener()
    async def on_member_join(self, member):
        guild = self.client.get_guild(GUILD_ID)
        general_channel = guild.get_channel(CHANNEL_ID)


        url = requests.get(member.avatar_url)
        avatar = Image.open(BytesIO(url.content))
        avatar = avatar.resize((285,285));
        bigsize = (avatar.size[0] * 3,  avatar.size[1] * 3)
        mask = Image.new('L', bigsize, 0)
        draw = ImageDraw.Draw(mask)
        draw.ellipse((0, 0) + bigsize, fill=255)
        mask = mask.resize(avatar.size, Image.ANTIALIAS)
        avatar.putalpha(mask)

        output = ImageOps.fit(avatar, mask.size, centering=(1420, 298))
        output.putalpha(mask)
        output.save('avatar.png')

        img = Image.open('welcomealpha.png')
        img.paste(avatar,(1408,265), avatar)
        img.save('wel.png')

        file = discord.File('wel.png')
        channel = self.client.get_channel(CHANNEL_ID)
        await channel.send(file=file)
        guild = self.client.get_guild(GUILD_ID)
        channel = guild.get_channel(CHANNEL_ID)

难道是机器人不知道如何区分 .gif.png ?如果是这种情况,机器人 识别 每个新用户的个人资料图片格式以便根据其格式操作 image/gif 的最有效方法是什么?

这里的错误信息很清楚:您原来的 Image 对象有 mode P,即它是一个调色板图像。当像你那样添加一个 alpha 通道时,你会得到模式 PA。正如 Pillow 告诉您的那样,不支持将模式 PAImage 对象保存为 PNG。由于您只想保存到一些没有任何动画的静态 PNG,我假设在开始时将 Image 对象转换为模式 RGB 就可以保存,这样您就可以得到 RGBA mode Image object 最后保存为 PNG 没有问题。

我从您的代码中摘录了以下内容并将转换添加到模式 RGB:

from PIL import Image, ImageDraw, ImageOps

avatar = Image.open('homer.gif').convert('RGB')
avatar = avatar.resize((285, 285))
bigsize = (avatar.size[0] * 3,  avatar.size[1] * 3)
mask = Image.new('L', bigsize, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((0, 0) + bigsize, fill=255)
mask = mask.resize(avatar.size, Image.ANTIALIAS)
avatar.putalpha(mask)

output = ImageOps.fit(avatar, mask.size, centering=(1420, 298))
output.putalpha(mask)
output.save('avatar.png')

GIF输入的是Homer;相应的 Image 对象具有模式 P:

导出的PNG如下;好像是GIF:

的第一帧

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
Pillow:        8.1.0
----------------------------------------