Skip to main content
 首页 » 编程设计

python之如何在 fastAPI 中返回图像

2025年05月04日20zhujiabin

使用 python 模块 fastAPI ,我不知道如何返回图像。在 flask 中我会做这样的事情:

@app.route("/vector_image", methods=["POST"]) 
def image_endpoint(): 
    # img = ... # Create the image here 
    return Response(img, mimetype="image/png") 

这个模块中对应的调用是什么?

请您参考如下方法:

如果内存中已经有图像的字节

使用您的自定义 content 和 media_type 返回一个 fastapi.responses.Response。

您还需要处理端点装饰器以使 FastAPI 将正确的媒体类型放入 OpenAPI 规范中。

@app.get( 
    "/image", 
 
    # Set what the media type will be in the autogenerated OpenAPI specification. 
    # fastapi.tiangolo.com/advanced/additional-responses/#additional-media-types-for-the-main-response 
    responses = { 
        200: { 
            "content": {"image/png": {}} 
        } 
    }, 
 
    # Prevent FastAPI from adding "application/json" as an additional 
    # response media type in the autogenerated OpenAPI specification. 
    # https://github.com/tiangolo/fastapi/issues/3258 
    response_class=Response 
) 
def get_image() 
    image_bytes: bytes = generate_cat_picture() 
    # media_type here sets the media type of the actual response sent to the client. 
    return Response(content=image_bytes, media_type="image/png") 

参见 Response documentation .

如果你的图片只存在于文件系统中

返回一个fastapi.responses.FileResponse。

参见 FileResponse documentation .


小心StreamingResponse

其他答案建议使用 StreamingResponse。 StreamingResponse 更难正确使用,所以我不推荐它,除非你确定你不能使用 Response 或 FileResponse。

特别是,这样的代码毫无意义。它不会以任何有用的方式“流式传输”图像。

@app.get("/image") 
def get_image() 
    image_bytes: bytes = generate_cat_picture() 
    # ❌ Don't do this. 
    image_stream = io.BytesIO(image_bytes) 
    return StreamingResponse(content=image_stream, media_type="image/png") 

首先,StreamingResponse(content=my_iterable) 通过迭代 my_iterable 提供的 block 进行流传输。但是当那个可迭代对象是 BytesIO 时,the chunks will be \n-terminated lines ,这对二值图像没有意义。

即使分块有意义,分块在这里也毫无意义,因为我们从一开始就拥有整个 image_bytes bytes 对象。我们也可以从一开始就将整个事情传递到 Response 中。我们不会通过从 FastAPI 获取数据来获得任何好处。

其次,StreamingResponse对应HTTP chunked transfer encoding . (这可能取决于您的 ASGI 服务器,但至少是 Uvicorn 的情况。)这不是分块传输编码的好用例。

当您事先不知道输出的大小时,并且您不想在开始将其发送给客户端之前等待收集所有数据以找出答案时,分块传输编码是有意义的。这可以适用于诸如提供慢速数据库查询结果之类的东西,但它通常不适用于提供图像。

不必要的分块传输编码可能是有害的。例如,这意味着客户端在下载文件时无法显示进度条。见: