web-dev-qa-db-fra.com

Comment lire un fichier image du compartiment S3 directement dans la mémoire?

J'ai le code suivant

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import boto3
s3 = boto3.resource('s3', region_name='us-east-2')
bucket = s3.Bucket('sentinel-s2-l1c')
object = bucket.Object('tiles/10/S/DG/2015/12/7/0/B01.jp2')
object.download_file('B01.jp2')
img=mpimg.imread('B01.jp2')
imgplot = plt.imshow(img)
plt.show(imgplot)

et il fonctionne. Mais le problème, c'est qu'il télécharge le fichier dans le répertoire actuel en premier. Est-il possible de lire un fichier et de le décoder sous forme d'image directement dans la RAM?

7
Dims

La réponse de Greg Merritt ci-dessous est la meilleure méthode.

J'aimerais suggérer d'utiliser le module NamedTemporaryFile in tempfile de Python. Il crée des fichiers temporaires qui seront supprimés lors de la fermeture du fichier (Merci à @NoamG)

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import boto3
import tempfile

s3 = boto3.resource('s3', region_name='us-east-2')
bucket = s3.Bucket('sentinel-s2-l1c')
object = bucket.Object('tiles/10/S/DG/2015/12/7/0/B01.jp2')
tmp = tempfile.NamedTemporaryFile()

with open(tmp.name, 'wb') as f:
    object.download_fileobj(f)
    img=mpimg.imread(tmp.name)
    # ...Do jobs using img
9
Hyeungshik Jung

Je suggérerais d'utiliser module io pour lire le fichier directement dans la mémoire, sans avoir à utiliser de fichier temporaire du tout.

Par exemple:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import boto3
import io

s3 = boto3.resource('s3', region_name='us-east-2')
bucket = s3.Bucket('sentinel-s2-l1c')
object = bucket.Object('tiles/10/S/DG/2015/12/7/0/B01.jp2')

file_stream = io.StringIO()
object.download_fileobj(file_stream)
img = mpimg.imread(file_stream)
# whatever you need to do

Vous pouvez également utiliser io.BytesIO si vos données sont binaires.

11
Greg Merritt

Le streaming de l'image est possible en spécifiant le format de fichier dans imread().

import boto3
from io import BytesIO
import matplotlib.image as mpimg
import matplotlib.pyplot as plt

resource = boto3.resource('s3', region_name='us-east-2')
bucket = resource.Bucket('sentinel-s2-l1c')

image_object = bucket.Object('tiles/10/S/DG/2015/12/7/0/B01.jp2')
image = mpimg.imread(BytesIO(image_object.get()['Body'].read()), 'jp2')

plt.figure(0)
plt.imshow(image)
5
Adrian Tofting
object = bucket.Object('tiles/10/S/DG/2015/12/7/0/B01.jp2')
img_data = object.get().get('Body').read()
0
Evgeniy