2011-07-13 153 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或某個對象實例)獲取圖像內容的方法。