【问题标题】:How to download an image from s3 and store it as a variable instead of storing it in a directory?如何从 s3 下载图像并将其存储为变量而不是将其存储在目录中?
【发布时间】:2021-10-20 02:25:26
【问题描述】:

我在 S3 上的存储桶中有几张图片,我的任务是为它们生成缩略图并将它们上传回同一存储桶中的另一个目录。如果上传了任何新图像,我将使用 AWS Lambda,因为我想自动执行我的 python 脚本来生成缩略图。

这是我目前所拥有的:

from botocore.exceptions import NoCredentialsError, ClientError
from os import listdir
from PIL import Image
import boto3
import botocore

def get_img_list():

    s3 = boto3.client('s3')
        response = s3.list_objects_v2(
            Bucket='imagesforgreendub',
            Prefix='photo_test/',
            )

    for val in response['Contents']:
        if val['Key'] != 'photo_test/':
            temp = val['Key']
            img_name = temp.split('/')
            if img_name[1] != '':
                thumb_name = 'thumb_' + img_name[1]
                print(thumb_name)
                dld_img(val['Key'], thumb_name)

上述函数只是从我的 S3 存储桶中获取图像的名称。

下一个功能是下载图像以及我遇到问题的地方。 download_file 要求我指定用于存储图像的名称/目录。问题是我计划在 AWS lambda 上运行它,但我认为它不会让我存储图像。所以我希望检索图像并将其存储在一个变量中,我可以将其传递给我的缩略图生成函数。

我发现这个线程 (Retrieve S3 file as Object instead of downloading to absolute system path) 说它以字符串形式检索内容,但是当我有一个图像文件并且我使用 PIL/Pillow 生成拇指时它将如何工作,所以我需要将图像传递为参数。

def dld_img(key_name, thumb_name):
    s3 = boto3.resource('s3')

    try:
        local_img = s3.Bucket('imagesforgreendub').download_file(key_name, 'my_local_image.jpg')


    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] == "404":
            print("The object does not exist.")
        else:
            raise

def img_thumb(img, thumb_name):

    MAX_SIZE = (100, 100)

    img.thumbnail(MAX_SIZE)
    s3 = boto3.client('s3')
    s3.upload_file(img, 'imagesforgreendub', '%s/%s' % ('thumb_test', thumb_name))

总结一下: 如何从 s3 下载图像并将其存储在一个变量中,然后我可以将其传递给我的 img_thumb 函数?

【问题讨论】:

    标签: python-3.x amazon-s3 aws-lambda boto3


    【解决方案1】:

    可以尝试以下方法从 s3 读取图像作为 Pillow 中的图像:

    import os
    
    import boto3
    
    from PIL import Image
    
    s3 = boto3.resource('s3')
    
    def image_from_s3(bucket, key):
    
        bucket = s3.Bucket(bucket)
        image = bucket.Object(key)
        img_data = image.get().get('Body').read()
    
        return Image.open(io.BytesIO(img_data))
    

    要调用它,您可以使用:

     img = image_from_s3(image_bucket, image_key)
    

    img 将是枕头图像,您应该可以将其传递给您的img_thumb

    【讨论】:

    • 还有一个问题, s3.upload_file(img, 'imagesforgreendub', '%s/%s' % ('thumb_test', thumb_name)) 要求第一行是文件名而不是一个变量名。如何克服?
    • @Bittu 我扩展了答案。
    猜你喜欢
    • 2021-06-24
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    相关资源
    最近更新 更多