繁体   English   中英

如何在 aiohttp 中发回图像/文件

[英]How to send back image/file in aiohttp

我需要知道如何在 aiohttp 中发回图像。 我编写了一个用于调整图像大小的服务器。 我使用了 aiohttp.web.FileResponse 但它需要保存文件并且有点问题(很多文件需要保存在硬盘上)。

有没有办法灵活地做到这一点(不保存文件)? 从图像字节可能还是什么? 我阅读了 aiohttp 文档,但没有做太多。

这是我试图做的:

  1. 文件响应

在这里我必须保存它以发送回复

image = tasks.get(key)  # PIL.Image
image.save('im_server/pil_{}.jpg'.format(key))  
resp = web.FileResponse(f'im_server/pil_{key}.jpg')
return resp
  1. 流响应

当我使用此代码提出请求时,我已经获得了文件(它正在上传到我的计算机上),但它不是图像。 如果我尝试将其作为图像打开,它会说文件损坏并且无法打开:(

image = tasks.get(key)  # PIL.Image
resp = web.StreamResponse(status=200)
resp.headers['Content-Type'] = 'Image/JPG'
await resp.prepare(request)
await resp.write(image.tobytes())
return resp

您可以使用tempfile.SpooledTemporaryFile来完成保存工作。 它旨在将临时文件存储在 memory 中,并且仅当文件大小超过max_size参数时才会将文件保存在磁盘上。 请注意,此参数默认为 0,因此您需要将其更改为合适的大小以避免将所有内容存储在磁盘上。 用法很简单, SpooledTemporaryFile会返回一个file_like object 句柄,你可以像普通文件一样写入它。 一旦你不需要它,只需将其关闭,它将自动从 memory 或磁盘中删除。 更多用法可以参考文档: https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile

您可以使用io.BytesIO

async def img_resize(req: web.Request):
    data = await req.post()
    url = data.get('url')
    width = data.get('width')
    height = data.get('height')

    if not all((url, width, height)):
        return web.HTTPNotFound()

    try:
        width = int(width)
        height = int(height)
    except ValueError:
        return web.HTTPError()

    async with ClientSession() as session:
        async with await session.get(url) as res:
            if res.status != 200:
                return web.HTTPNotFound()

            img_raw = await res.read()

    im = Image.open(BytesIO(img_raw))
    im = im.resize((width, height), Image.BICUBIC)

    stream = BytesIO()
    im.save(stream, "JPEG")

    return web.Response(body=stream.getvalue(), content_type='image/jpeg')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM