2011-07-13 212 views
16

我试图调整后的图像上传到S3:上传调整图像S3

fp = urllib.urlopen('http:/example.com/test.png') 
img = cStringIO.StringIO(fp.read()) 

im = Image.open(img) 
im2 = im.resize((500, 100), Image.NEAREST) 
AK = 'xx' # Access Key ID 
SK = 'xx' # Secret Access Key 

conn = S3Connection(AK,SK) 
b = conn.get_bucket('example') 
k = Key(b) 
k.key = 'example.png' 
k.set_contents_from_filename(im2) 

,但我得到一个错误:

in set_contents_from_filename 
    fp = open(filename, 'rb') 
TypeError: coercing to Unicode: need string or buffer, instance found 
+0

看的类型'im2' –

回答

54

在上传到s3之前,您需要将输出图像转换为一组字节。你可以写的图像文件,然后上传文件,或者你可以使用一个cStringIO对象,以避免写入磁盘,因为我在这里所做的:

import boto 
import cStringIO 
import urllib 
import Image 

#Retrieve our source image from a URL 
fp = urllib.urlopen('http://example.com/test.png') 

#Load the URL data into an image 
img = cStringIO.StringIO(fp.read()) 
im = Image.open(img) 

#Resize the image 
im2 = im.resize((500, 100), Image.NEAREST) 

#NOTE, we're saving the image into a cStringIO object to avoid writing to disk 
out_im2 = cStringIO.StringIO() 
#You MUST specify the file type because there is no file name to discern it from 
im2.save(out_im2, 'PNG') 

#Now we connect to our s3 bucket and upload from memory 
#credentials stored in environment AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY 
conn = boto.connect_s3() 

#Connect to bucket and create key 
b = conn.get_bucket('example') 
k = b.new_key('example.png') 

#Note we're setting contents from the in-memory string provided by cStringIO 
k.set_contents_from_string(out_im2.getvalue()) 
+0

在哪里你在这个代码中添加一个mimetype?我正在将文件上传到S3,但它们显示为无法读取的文件。 – captDaylight

+3

@captDaylight - 要设置MIME类型,请在set_contents_from_string调用中添加一个标题= {“Content-Type”:“image/png”}作为参数。 Boto默认会尝试猜测MIME类型,但是这可以让你手动设置它。 – secretmike

+0

很好的回答。我建议的一个改变是使用awesome [requests模块](http://docs.python-requests.org/en/latest/)而不是过时的'urllib'模块。 – tatlar

0

我的猜测是,Key.set_contents_from_filename期待一个字符串参数,但是您传递的是im2,这是Image.resize返回的其他一些对象类型。我认为你需要将你的已调整大小的图像作为名称文件写入文件系统,然后将该文件名传递给k.set_contents_from_filename。否则,请在Key类中查找另一种可以从内存结构(StringIO或某个对象实例)获取图像内容的方法。