Send image from memory

半城伤御伤魂 提交于 2020-05-15 07:45:59

问题


I am trying to implement a system for a Discord bot that dynamically modifies images and sends them to the bot users. To do that, I decided to use the Pillow (PIL) library, since it seemed simple and straightforward for my purposes.

Here is an example of my working code. It loads an example image, as a test modification, draws two diagonal lines on it, and outputs the image as a Discord message:

# Open source image
img = Image.open('example_image.png')

# Modify image
draw = ImageDraw.Draw(img)
draw.line((0, 0) + img.size, fill=128)
draw.line((0, img.size[1], img.size[0], 0), fill=128)

# Save to disk and create discord file object
img.save('tmp.png', format='PNG')
file = discord.File(open('tmp.png', 'rb'))

# Send picture as message
await message.channel.send("Test", file=file)

This results in the following message from my bot:

Discord message with the edited image as result

This works; however, I would like to omit the step of saving the image to the hard drive and loading it again, since that seems rather inefficient and unnecessary. After some googling I came across following solution; however, it doesn't seem to work:

# Save to disk and create discord file object
# img.save('tmp.png', format='PNG')
# file = discord.File(open('tmp.png', 'rb'))

# Save to memory and create discord file object
arr = io.BytesIO()
img.save(arr, format='PNG')
file = discord.File(open(arr.getvalue(), 'rb'))

This results in the following error message:

Traceback (most recent call last):
    File "C:\Users\<username>\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\client.py", line 270, in _run_event
        await coro(*args, **kwargs)
    File "example_bot.py", line 48, in on_message
        file = discord.File(open(arr.getvalue(), 'rb'))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte

回答1:


discord.File supports passing io.BufferedIOBase as the fp parameter.
io.BytesIO inherits from io.BufferedIOBase.
This means that you can directly pass the instance of io.BytesIO as fp to initialize discord.File, e.g.:

arr = io.BytesIO()
img.save(arr, format='PNG')
arr.seek(0)
file = discord.File(arr)

Another example of this can be seen in the How do I upload an image? section of the FAQ in discord.py's documentation.



来源:https://stackoverflow.com/questions/60006794/send-image-from-memory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!