2011-07-13 40 views
16

Tôi đang cố gắng để tải lên hình ảnh thay đổi kích cỡ để S3:Tải lên thay đổi kích cỡ ảnh để 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) 

nhưng tôi nhận được một lỗi:

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

Nhìn vào loại 'im2' –

Trả lời

54

Bạn cần chuyển đổi hình ảnh đầu ra thành một tập hợp các byte trước khi có thể tải lên s3. Bạn có thể ghi hình ảnh vào một tệp, sau đó tải lên tệp hoặc bạn có thể sử dụng đối tượng cStringIO để tránh ghi vào đĩa như tôi đã thực hiện ở đây:

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

Nơi nào bạn thêm một mimetype trong mã này? Tôi đang nhận tệp để tải lên S3 nhưng chúng xuất hiện dưới dạng tệp không đọc được. – captDaylight

+3

@captDaylight - Để đặt loại mime thêm tiêu đề = {"Content-Type": "image/png"} làm tham số cho lệnh set_contents_from_string. Boto sẽ cố gắng đoán loại mime theo mặc định nhưng điều này sẽ cho phép bạn thiết lập nó theo cách thủ công. – secretmike

+0

Câu trả lời hay. Một thay đổi tôi khuyên bạn nên sử dụng [mô-đun yêu cầu] tuyệt vời (http://docs.python-requests.org/en/latest/) thay vì mô-đun 'urllib' đã lỗi thời. – tatlar

0

tôi đoán là Key.set_contents_from_filename hy vọng một đối số chuỗi duy nhất, nhưng bạn đang đi qua trong im2, là một số loại đối tượng khác được trả về bởi Image.resize. Tôi nghĩ rằng bạn sẽ cần phải viết hình ảnh được thay đổi kích cỡ của bạn ra hệ thống tập tin dưới dạng tệp tên và sau đó chuyển tên tệp đó đến k.set_contents_from_filename. Nếu không, hãy tìm một phương thức khác trong lớp Key có thể lấy nội dung hình ảnh từ một cấu trúc trong bộ nhớ (StringIO hoặc một số cá thể đối tượng).

Các vấn đề liên quan