2011-07-13 18 views
16

Estoy tratando de subir la imagen redimensionada a S3:Subir cambiar el tamaño de imagen a 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) 

pero me da un error:

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

Mira el tipo de 'im2' –

Respuesta

54

Necesita convertir su imagen de salida en un conjunto de bytes antes de poder cargarla en s3. Usted puede escribir la imagen en un archivo y luego subir el archivo, o puede utilizar un objeto cStringIO para evitar escribir en el disco como he hecho aquí:

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

¿Dónde usted agrega un tipo MIME en este código? Estoy recibiendo archivos para subir a S3 pero están apareciendo como archivos ilegibles. – captDaylight

+3

@captDaylight - Para establecer el tipo de mime, agregue un encabezado = {"Content-Type": "image/png"} como parámetro a la llamada set_contents_from_string. Boto intentará adivinar el tipo de mimo por defecto, pero esto le permitirá configurarlo manualmente. – secretmike

+0

Gran respuesta. Un cambio que recomiendo es usar el impresionante [módulo de solicitudes] (http://docs.python-requests.org/en/latest/) en lugar del obsoleto módulo 'urllib'. – tatlar

0

Mi conjetura es que Key.set_contents_from_filename espera un único argumento de cadena, pero está pasando en im2, que es algún otro tipo de objeto devuelto por Image.resize. Creo que tendrá que escribir su imagen redimensionada en el sistema de archivos como un archivo de nombre y luego pasar ese nombre de archivo al k.set_contents_from_filename. De lo contrario, busque otro método en la clase Key que pueda obtener el contenido de la imagen desde una construcción en memoria (StringIO o alguna instancia de objeto).

Cuestiones relacionadas