I have a bunch of images in my S3 bucket folder.
I have a list of keys from S3 (img_list) and I can read and display the images:
key = img_list[0]
bucket = s3_resource.Bucket(bucket_name)
img = bucket.Object(key).get().get('Body').read()
I have a function for that:
def image_from_s3(bucket, key):
bucket = s3_resource.Bucket(bucket)
image = bucket.Object(key)
img_data = image.get().get('Body').read()
return Image.open(io.BytesIO(img_data))
Now what I want is to read the image using OpenCV but I am getting an error:
key = img_list[0]
bucket = s3_resource.Bucket(bucket_name)
img = bucket.Object(key).get().get('Body').read()
cv2.imread(img)
SystemError Traceback (most recent call last)
<ipython-input-13-9561b5237a85> in <module>
2 bucket = s3_resource.Bucket(bucket_name)
3 img = bucket.Object(key).get().get('Body').read()
----> 4 cv2.imread(img)
SystemError: <built-in function imread> returned NULL without setting an error
Please advise how to read it in the right way?
Sorry, I got it wrong in the comments. This code sets up a PNG file in a memory buffer to simulate what you get from S3:
#!/usr/bin/env python3
from PIL import Image, ImageDraw
import cv2
# Create new solid red image and save to disk as PNG
im = Image.new('RGB', (640, 480), (255, 0, 0))
im.save('image.png')
# Slurp entire contents, raw and uninterpreted, from disk to memory
with open('image.png', 'rb') as f:
raw = f.read()
# "raw" should now be very similar to what you get from your S3 bucket
Now, all I need is this:
nparray = cv2.imdecode(np.asarray(bytearray(raw)), cv2.IMREAD_COLOR)
So, you should need:
bucket = s3_resource.Bucket(bucket_name)
img = bucket.Object(key).get().get('Body').read()
nparray = cv2.imdecode(np.asarray(bytearray(img)), cv2.IMREAD_COLOR)
Hope This will be Best Solution For Mentioned Requirement, To read The Images from s3 bucket using URLs..!
import os
import logging
import boto3
from botocore.client import Config
from botocore.exceptions import ClientError
import numpy as np
import urllib
import cv2
s3_signature ={
'v4':'s3v4',
'v2':'s3'
}
def create_presigned_url(bucket_name, bucket_key, expiration=3600, signature_version=s3_signature['v4']):
s3_client = boto3.client('s3',
aws_access_key_id="AWS_ACCESS_KEY",
aws_secret_access_key="AWS_SECRET_ACCESS_KEY",
config=Config(signature_version=signature_version),
region_name='ap-south-1'
)
try:
response = s3_client.generate_presigned_url('get_object',
Params={'Bucket': bucket_name,
'Key': bucket_key},
ExpiresIn=expiration)
print(s3_client.list_buckets()['Owner'])
for key in s3_client.list_objects(Bucket=bucket_name,Prefix=bucket_key)['Contents']:
print(key['Key'])
except ClientError as e:
logging.error(e)
return None
# The response contains the presigned URL
return response
def url_to_image(URL):
resp = urllib.request.urlopen(url)
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
return image
seven_days_as_seconds = 604800
generated_signed_url = create_presigned_url(you_bucket_name, bucket_key,
seven_days_as_seconds, s3_signature['v4'])
print(generated_signed_url)
image_complete = url_to_image(generated_signed_url)
#just debugging Purpose to show the read Image
cv2.imshow('Final_Image',image_complete)
cv2.waitKey(0)
cv2.destroyAllWindows()
Use For Loop to iterate to all Keys In The KeyList. Just Before calling the Function create_presigned_url.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With