@MIHUTKA

Как убрать эту ошибку?

Скриншот фрагмента кода удалён модератором.

@tasks.loop(minutes = 10)
    async def check_vc(self):
        base = sqlite3.connect('cogs/base.db')
        cur = base.cursor()
        im = Image.open('bane.gif')
        frames = []
        ImageDraw.Draw(im)
        guild = self.bot.get_guild(1084432275921453126)
        vcusrs = sum(len(vc.members) for vc in guild.voice_channels)
        vcount = ImageFont.truetype("chiller.ttf", 80)
        guildount = ImageFont.truetype("chiller.ttf", 35)
        nametext = ImageFont.truetype("chiller.ttf", 70)
        for frame in ImageSequence.Iterator(im):
            frame = frame.convert("RGBA")
            d = ImageDraw.Draw(frame)
            tp = cur.execute(f'SELECT userid FROM vchour ORDER BY time DESC LIMIT 1').fetchone()

            if tp != None:
                memb = await guild.fetch_member(tp[0])
                name = memb.display_name
                if len(name) > 7:
                    name = name[:7] + "..."
                d.text((155, 215), name, (255, 255, 255), font=nametext)
                avatar_image = Image.open(BytesIO(requests.get(memb.display_avatar).content)).resize((90, 90))
                avatar_mask = Image.new('L', avatar_image.size, 0)
                draw = ImageDraw.Draw(avatar_mask)
                draw.ellipse((0, 0) + avatar_image.size, fill=225)
                avatar_image.putalpha(avatar_mask)
                for i in range(4):
                    frame.alpha_composite(avatar_image, (47, 209))

            d.text((675, 250), str(vcusrs), (255, 255, 255), font=vcount)
            d.text((340, 190), str(guild.member_count), (255, 255, 255), font=guildount)

            b = io.BytesIO()
            frame.save(b, format="GIF")
            frame = Image.open(b)
            frames.append(frame)
        frames[0].save('out.gif', save_all=True, append_images=frames[1:])
        with open("out.gif", 'rb') as f:
            contents = f.read()
            await guild.edit(banner = contents)


Task exception was never retrieved
future: <Task finished name='Task-26' coro=<Loop._loop() done, defined at C:\Program Files\Python311\Lib\site-packages\disnake\ext\tasks\__init__.py:146> exception=ValueError('images do not match')>
Traceback (most recent call last):
  File "C:\Program Files\Python311\Lib\site-packages\disnake\ext\tasks\__init__.py", line 192, in _loop
    raise exc
  File "C:\Program Files\Python311\Lib\site-packages\disnake\ext\tasks\__init__.py", line 163, in _loop
    await self.coro(*args, **kwargs)
  File "E:\work\love\moder\cogs\banner.py", line 66, in check_vc
    frame.alpha_composite(avatar_image, (47, 209))
  File "C:\Program Files\Python311\Lib\site-packages\PIL\Image.py", line 1784, in alpha_composite
    result = alpha_composite(background, overlay)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\site-packages\PIL\Image.py", line 3317, in alpha_composite
    return im1._new(core.alpha_composite(im1.im, im2.im))
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: images do not match
  • Вопрос задан
  • 152 просмотра
Решения вопроса 1
SoreMix
@SoreMix Куратор тега Python
yellow
Если проблема в том, что возвращается анимация, я думаю можно попробовать следующее: у avatar_image тип Asset

Можно проверять что аватар является анимацией, и делать что нибудь в духе
  • Брать default аватар
  • Менять формат изображения


Плюс, disnake естественно даёт возможность читать файл сразу, не нужно слать доп. запросы (он так же даёт возможность делать ресайзы)

Для первого варианта как-то так:
avatar_obj = memb.display_avatar if memb.display_avatar.is_animated() else memb.default_avatar
avatar_obj = avatar_obj.read()

avatar_image = Image.open(BytesIO(avatar_obj)).resize((90, 90))


Для второго варианта можно попробовать брать аватар, ресайзить, и сразу менять формат. По-идее это будет универсальным решением, я бы наверное использовал его

Не знаю какие должны быть правильные format и size, сам не пишу под дискорд, но по логике как-то так наверное:
avatar_obj = memb.display_avatar.replace(size=90, format='jpg').read()
avatar_image = Image.open(BytesIO(avatar_obj))
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
phaggi
@phaggi Куратор тега Python
лужу, паяю, ЭВМы починяю
Признаться, в такой огромной функции разбираться вообще неохота.

Разделите функцию по такому принципу:
основная функция делает это, вот это, то и еще вот то, значит надо сделать на каждое из перечисленного по доп.функции, и в основной функции только вызывать их и передавать данные, полученные от одной функции, в другие.
Тогда можно будет отлаживать каждую функцию по-отдельности.

В общем, вашему коду нужен рефакторинг, а уж после этого, если останется ошибка, ее можно будет проще локализовать и исправить.
Ответ написан
Vindicar
@Vindicar
RTFM!
Размер двух накладываемых изображений точно одинаков? Проверь.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы