FastAPI中PIL生成PNG在Jinja2模板无法渲染,求解决方案
问题分析与修复
核心错误点
- 第一段代码错误:直接调用
Image.tobytes()获取的是原始像素数据,并非经过编码的标准图片文件(如JPEG/PNG),浏览器无法解析裸像素数据生成图像。 - 第二段代码错误:
base64.b64encode()返回的是字节对象(bytes),未解码为UTF-8字符串,Jinja2渲染时会保留b'...'的字节标识,导致Data URI格式完全无效。
修正后的代码
Python 端点代码
import io import base64 from PIL import Image from fastapi import Request, status from fastapi.templating import Jinja2Templates templates = Jinja2Templates(directory="templates") # 确保模板目录路径正确 @api.get("/test_image", status_code=status.HTTP_200_OK) def test_image(request: Request): # 创建测试图像 im = Image.new('RGB', (1000, 1000), 'red') # 创建字节缓冲区,将图像以PNG格式写入 buffer = io.BytesIO() im.save(buffer, format='PNG') # 将缓冲区内容编码为base64字符串 base64_encoded_image = base64.b64encode(buffer.getvalue()).decode('utf-8') return templates.TemplateResponse( "display_image.html", {"request": request, "myImage": base64_encoded_image} )
HTML 模板代码
<html> <head> <title>Display Uploaded Image</title> </head> <body> <h1>My Image</h1> <img src="data:image/png;base64,{{ myImage | safe }}"> </body> </html>
关键说明
- 使用标准图像格式编码:必须通过
Image.save()将图像以PNG/JPEG等标准格式写入缓冲区,确保数据是浏览器可识别的完整图片文件。 - base64字节转字符串:
base64.b64encode()的结果必须用.decode('utf-8')转换为字符串,避免Jinja2渲染时出现字节标识破坏Data URI结构。 - 匹配Data URI格式:HTML中
src的image/png要和后端保存的图像格式一致,确保浏览器能正确解析编码内容。
内容的提问来源于stack exchange,提问作者Brad Allen
相关产品推荐
相关产品推荐

