如何在Python中上传Base64编码字符串到S3并在HTML文件中访问该URL

2 投票
3 回答
13518 浏览
提问于 2025-04-18 00:25

我有一个base64字符串。这个字符串实际上是一个图片的base64编码。现在我想把这个文件上传到S3上,然后可以通过S3的链接直接在我的浏览器或者HTML文件中访问这个图片。

我试过几种方法,但都没能在浏览器中打开图片,结果都是直接下载到我的电脑上。

方法1:使用botoS3的方法set_contents_from_string。

方法2:把base64转换成StringIO,然后使用set_contents_from_file。

方法3:把base64保存到临时文件中,然后使用set_contents_from_file的方法。

我用的这些方法都只是让文件在浏览器中下载,而不是识别成图片。

3 个回答

4

这段代码是用来处理一些数据的。它可能会涉及到一些复杂的操作,但我们可以把它拆解成简单的部分来理解。

首先,代码的开头部分通常是一些设置,比如导入需要用到的库或者定义一些变量。这些都是为了后面能顺利运行代码做准备。

接下来,代码中可能会有一些循环或者条件判断。这就像是在说:“如果这个条件成立,就做这件事;否则,就做另一件事。” 这样的结构可以让程序根据不同的情况做出不同的反应。

最后,代码的结尾部分一般是输出结果,或者是将处理后的数据保存到某个地方。这样我们就能看到程序的运行结果,或者把结果留着以后用。

总的来说,这段代码的目的是为了处理数据,虽然具体的实现可能会有点复杂,但理解它的基本结构和逻辑就能帮助我们更好地掌握编程。

from boto.s3.connection import S3Connection
from boto.s3.key import Key
import base64
picture = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlcAAAMfCAY...example"
conn = S3Connection('ACCESS', 'SECRET', host='HOST')
bucket = conn.get_bucket('BUCKET')
k = Key(bucket)
k.key = 'filename.png'
picture = picture.replace("data:image/png;base64,","")
k.set_contents_from_string(base64.b64decode(picture))
k.set_metadata('Content-Type', 'image/png')
6

set_contents_from_string(base64.b64decode(data)) 这个方法对我有效

完整代码

import boto
from boto.s3.connection import S3Connection
from boto.s3.key import Key
# import urllib
# from io import BytesIO
AWS_ACCESS_KEY = os.environ.get('AWS_ACCESS_KEY') 
AWS_SECRET_KEY = os.environ.get('AWS_SECRET_KEY')
AWS_BUCKET_NAME = os.environ.get('S3_BUCKET_NAME')
import base64

我在一个django视图中做这个,所以我先读取base64数据,并把它赋值给一个叫 cover_art 的变量。然后我像这样把它保存到S3上:

connection = boto.connect_s3()
bucket = connection.get_bucket(AWS_BUCKET_NAME)
cloudfile = Key(bucket)
path = "images/" + me.username + "/" + "cover-image-001.jpg"
cloudfile.key = path
cloudfile.set_contents_from_string(base64.b64decode(cover_art))
cloudfile.set_metadata('Content-Type', 'image/jpeg') # from https://stackoverflow.com/a/22730676 and https://stackoverflow.com/questions/16156062/using-amazon-s3-boto-library-how-can-i-get-the-url-of-a-saved-key
cloudfile.set_acl('public-read')

额外说明

几个小时前我对base64编码完全不懂,所以也不知道该用boto做什么。如果你不小心给boto传了错误的东西,这里有个关于我用的那个变量“cover_art”的额外说明。

假设数据看起来是这样的:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFR...

如果我想在网页上显示这个图片,我需要把它放成这样:

<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFR...">

不过在Python代码中,我给boto的部分是没有前面的介绍的。所以我的变量看起来是这样的:

cover_art = "/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFR..."

其实我是从一个表单中收集这个数据,表单的样子是这样的:

<input name="cover_art" type="hidden" value="/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQV...">

(如果你也在用表单,并想在提交后在浏览器中检查这个数据,可以试试用JavaScript抓取表单,然后显示出来,像这样 alert(theForm.innerHTML))

注意,没有奇怪的字符,它看起来并不是 ÿØÿà...

(希望你能从我用的语言看出来,我还是个新手!)

顺便说一下,我发这个是因为我不知道为什么 set_contents_from_file(file_obj) 方法对我没用... 不过谢谢你分享你的答案,很高兴看到这个方法对你有效。

1

我问题的答案是使用boto的set_meta_data方法,并把内容类型设置为'image/jpeg'。这样就达到了我的目的。现在我可以通过公共网址在浏览器中打开这个图片了。

conn = boto.connect_s3(AWS_ACCESS_KEYXXX, AWS_SECRET_KEYXXX)
bucket = conn.get_bucket(AWS_BUCKET_NAMEXXX)
k = Key(bucket)
k.key = s3_file_name
k.set_metadata('Content-Type', 'image/jpeg')
k.set_contents_from_file(file_obj)

撰写回答