You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask中如何在<img>标签显示从S3读取的PIL图片?

解决Flask前端无法显示S3获取图片的问题

问题原因

你直接把PIL的PngImageFile对象传给了模板,浏览器的<img>标签的src属性需要的是图片的URL或者Base64编码的图片数据,而不是Python对象,所以才会显示对象的字符串表示。

解决方案

有两种常用方法可以解决这个问题:

方法1:将图片转换为Base64编码字符串

修改read_froms3img函数,返回Base64编码的图片数据,而不是PIL对象:

import base64
import io
import boto3
from PIL import Image

def read_froms3img(image_name):
    ep_url=URL
    access_id=ID_KEY
    access_key=SECRET_KEY
    
    s3_resource = boto3.resource(service_name = "s3",endpoint_url=ep_url,  
                                 aws_access_key_id=access_id,   
                                 aws_secret_access_key=access_key)

    bucket = s3_resource.Bucket(s3_bucket)
    image = bucket.Object('Images/plot.png')
    img_data = image.get().get('Body').read()

    # 将图片转换为Base64编码
    img_base64 = base64.b64encode(img_data).decode('utf-8')
    # 返回带MIME类型的Base64字符串,供img标签使用
    return f"data:image/png;base64,{img_base64}"

视图函数调用:

contents = read_froms3img("plot.png")
return render_template('data.html', form_data = form_data, html_code = html, filename = contents)

HTML部分保持原代码即可:

<img src="{{filename}}" height="50%" width="65%">

方法2:生成S3图片的预签名URL

如果图片文件较大,Base64会增加数据体积,推荐使用S3的预签名URL,这个URL是临时可访问的,无需将图片数据传到服务器:

import boto3

def get_s3_presigned_url(image_name):
    ep_url=URL
    access_id=ID_KEY
    access_key=SECRET_KEY
    
    s3_client = boto3.client(service_name = "s3",endpoint_url=ep_url,  
                             aws_access_key_id=access_id,   
                             aws_secret_access_key=access_key)

    # 生成预签名URL,有效期设置为3600秒(1小时),可按需调整
    presigned_url = s3_client.generate_presigned_url('get_object',
                                                     Params={'Bucket': s3_bucket,
                                                             'Key': 'Images/plot.png'},
                                                     ExpiresIn=3600)
    return presigned_url

视图函数调用:

contents = get_s3_presigned_url("plot.png")
return render_template('data.html', form_data = form_data, html_code = html, filename = contents)

HTML部分同样无需修改,直接使用{{filename}}作为src的值即可。

注意事项

  • 方法1适合小尺寸图片,Base64会使图片体积增加约30%;
  • 方法2适合大图片,预签名URL的有效期可根据需求调整,避免长期暴露;
  • 确保S3存储桶的权限配置正确,你的AWS密钥需要具备对应的get_object权限。

内容的提问来源于stack exchange,提问作者SM079

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 11:31:40