如何从Numpy数组创建JPEG文件并使用boto3将其上传到AWS S3?

ki1q1bka  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(79)

我在内存中有一个Numpy数组,它代表一个图像。我想使用boto3将其上传到AWS S3。
我尝试了四种不同的方法:

import numpy as np
import boto3
from PIL import Image

# Mock image
np_image = np.zeros((height, width, channels), dtype=np.uint8) 

# 1st approach - using io.BytesIO()
image = io.BytesIO(np_image)

# 2nd approach - using PIL.Image
image = Image.fromarray(np_image)

# 3rd approach - using io.BytesIO() and PIL.Image
image = Image.fromarray(np_image)
byte_io = io.BytesIO()
image.save(byte_io, format="jpeg")

# Upload image using boto3
s3.upload_fileobj(
    Fileobj=image,
    Bucket=BUCKET_NAME,
    ExtraArgs={
        "ContentType": "image/jpeg"
    }
)

所有这些都不起作用,因为我得到了错误ValueError:Fileobj必须实现read..
到目前为止,唯一“有效”的是以下内容:

# 4th approach - using tobytes() from numpy.ndarray

io.BytesIO(np_image.tobytes())

使用此方法,文件成功上载。但是,文件已损坏,当我打开图像时显示:

一个解决方案是将文件保存在磁盘中,然后上传,但我认为这效率不高。

qacovj5a

qacovj5a1#

您需要创建图像文件并将该文件上传到S3。一种方法是调用Image.save(),将数据保存到内存缓冲区,然后使用S3.put_object()上传该数据:

# Create a simple array, with red in the top left corner, 
# and blue in the bottom right corner
import numpy
np_array = numpy.zeros((100, 100, 3), numpy.uint8)
np_array[0:40, 0:40] = (255, 0, 0)
np_array[60:100, 60:100] = (0, 0, 255)

# Generate the image file
from PIL import Image
import io
im = Image.fromarray(np_array)
bits = io.BytesIO()
im.save(bits, "png")

# Upload this file to S3
import boto3
# Seek back to the beginning of the file
bits.seek(0, 0)
s3 = boto3.client('s3')
# Make the file public for this demo, and set the content type
s3.put_object(
    Bucket=example_bucket, Key=example_key, 
    Body=bits, 
    ACL="public-read", ContentType="image/png",
)

相关问题