【问题标题】:Upload resized image to S3将调整大小的图像上传到 S3
【发布时间】:2011-10-04 20:34:18
【问题描述】:

我正在尝试将调整大小的图像上传到 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

【问题讨论】:

    标签: python amazon-s3 python-imaging-library boto


    【解决方案1】:

    您需要将输出图像转换为一组字节,然后才能上传到 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())
    

    【讨论】:

    • 在这段代码中你在哪里添加了 mimetype?我正在获取要上传到 S3 的文件,但它们显示为不可读的文件。
    • @captDaylight - 要设置 mime 类型,请将 headers={"Content-Type": "image/png"} 作为参数添加到 set_contents_from_string 调用。默认情况下,Boto 会尝试猜测 mime 类型,但这将允许您手动设置它。
    • 很好的答案。我建议的一项更改是使用很棒的 requests module 而不是过时的 urllib 模块。
    • @tatlar 我同意,请求比 urllib 好得多。我只在这里使用它,因为它是原始海报使用的。
    • 谢谢@secretmike!这是唯一一个清楚解释这一点的在线帖子
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:
      print ("loading object", input_bucket, input_key)
      response = s3client.get_object(Bucket=input_bucket, Key=input_key)
      print("s3 get object response", response)
      
      body = response['Body']
      
      image = Image.open(body)
      
      print ("generating thumbnail", output_width, output_height)
      
      thumbnail = resizeimage.resize_thumbnail(
          image, [output_width, output_height])
      body.close()
      
      print ("saving thumbnail", output_format)
      
      with io.BytesIO() as output:
          thumbnail.save(output, output_format)
      
          print ("uploading thumbnail", output_bucket, output_key)
          output.seek(0)
          s3client.put_object(Bucket=output_bucket, Key=output_key,
                              Body=output, ContentType=output_content_type)
      

      【讨论】:

      • 我在 lambda 服务中得到了这个工作,流入流出。
      猜你喜欢
      • 1970-01-01
      • 2023-04-11
      • 2014-11-16
      • 2013-07-12
      • 2011-09-18
      • 1970-01-01
      • 1970-01-01
      • 2013-03-26
      • 2015-11-18
      相关资源
      最近更新 更多