2016-12-22 5 views
0

Я работаю с функцией AWS Lambda, написанной на python 2.7x, которая загружает, сохраняет в/tmp, а затем загружает файл изображения обратно в ведро.Сохранение изображений AWS S3 теряет метаданные

Мои метаданные изображения начинаются в оригинальном ведре с заголовками http, такими как Content-Type = image/jpeg и другими.

После сохранения мое изображение с PIL, все заголовки ушли, и я остался с Content-Type = двоичный/октет-поток

Из того, что я могу сказать, image.save теряет заголовки из-за способа PIL работает. Как сохранить метаданные или хотя бы применить их к новому сохраненному изображению?

Я видел сообщение, предполагающее, что эти метаданные находятся в exif, но я попытался получить exif-информацию из исходного файла и применить к сохраненному файлу без везения. В любом случае, я не понимаю, что это данные exif.

Частичный код, чтобы дать представление о том, что я делаю:

def resize_image(image_path): 
    with Image.open(image_path) as image: 
    image.save(upload_path, optimize=True) 

def handler(event, context): 
    global upload_path 
    for record in event['Records']: 
     bucket = record['s3']['bucket']['name'] 
     key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode("utf8")) 

     download_path = '/tmp/{}{}'.format(uuid.uuid4(), file_name) 
     upload_path = '/tmp/resized-{}'.format(file_name) 

     s3_client.download_file(bucket, key, download_path) 

     resize_image(download_path) 
     s3_client.upload_file(upload_path, '{}resized'.format(bucket), key) 

Благодаря Сергею, я изменил к использованию get_object но ответ отсутствует Metadata:

response = s3_client.get_object(Bucket=bucket,Key=key) 

ответ = {u'Body ':, u'AcceptRanges': 'bytes', u'ContentType ':' image/jpeg ',' ResponseMetadata ': {' HTTPStatusCode ': 200,' RetryAttempts ': 0,' HostId ':' au30hBMN37/ti0WCfDqlb3t9ehainumc9onVYWgu + CsrHtvG0u/zmgcOIvCCBKZgQrGoooZoW9o = ',' RequestId ':' 1A94D7F01914A787 ',' HTTPHeaders ': {' content-length ':' 84053 ',' x-amz-id-2 ':' au3 0hBMN37/ti0WCfDqlb3t9ehainumc9onVYWgu + CsrHtvG0u/zmgcOIvCCBKZgQrGoooZoW9o = ',' accept-range ':' bytes ',' expires ':' Sun, 01 Jan 2034 00:00:00 GMT ',' server ':' AmazonS3 ',' last-modified ':' Fri, 23 Dec 2016 15:21:56 GMT ',' x-amz-request-id ':' 1A94D7F01914A787 ',' etag ':' "9ba59e5457da0dc40357f2b53715619d" ',' cache-control ':' max-age = 2592000, public ',' date ':' Fri, 23 Dec 2016 15:21:58 GMT ',' content-type ':' image/jpeg '}}, u'LastModified': datetime.datetime (2016, 12 , 23, 15, 21, 56, tzinfo = tzutc()), u'ContentLength ': 84053, u'Expires': datetime.datetime (2034, 1, 1, 0, 0, tzinfo = tzutc()), u 'ETag': '9ba59e5457da0dc40357f2b53715619d "', u'CacheControl ': 'макс возраста = 2592000, общественное', u'Metadata': {}}

Если я использую: метаданные = ответ [ 'ResponseMetadata'] ['HTTPHeaders']

metadata = {'content-length': '84053', 'x-amz-id-2': 'f5UAhWzx7lulo3cMVF8hdVRbHnhdnjHWRDl + LDFkYm9pubjL0A01L5yWjgDjWRE4TjRnjqDeA0U =', 'accept-range': 'bytes', 'expires': 'Sun, 01 Jan 2034 00:00:00 GMT ',' server ':' AmazonS3 ',' last-modified ':' Fri, 23 Dec 2016 15:47:09 GMT ',' x-amz-request-id ':' 4C69DF8A58EF3380 ',' etag ':' "9ba59e5457da0dc40357f2b53715619d" ',' cache-control ':' max-age = 2592000, public ',' date ':' Fri, 23 Dec 2016 15:47:10 GMT ',' content-type «: 'изображение/JPEG}

Сохранение с put_object

s3_client.put_object(Bucket=bucket+'resized',Key=key, Metadata=metadata, Body=downloadfile) 

создает целую кучу дополнительных метаданных в s3, включая тот факт, что она не сохраняет тип содержимого как изображение/JPEG, а в двоичной форме/octet-stream и создает метаданные x-amz-meta-content-type = image/jpeg

ответ

3

Вы вводите в заблуждение метаданные S3, хранящиеся AWS S3 вместе с объектом и метаданные EXIF, хранящиеся внутри самого файла ,

download_file() не получает атрибуты объекта из S3.Вы должны использовать get_object() вместо: https://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.get_object

Затем вы можете использовать put_objects() с теми же атрибутами, чтобы загрузить новый файл: https://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.put_object

+0

Спасибо! Я почти там. get_object возвращает пустые метаданные. Любая идея, почему это может быть? См. Вопрос для вывода –

+0

Получение метаданных в 'boto3' является суперразмерным. Вот вам один-лайнер: 'print (boto3.resource ('s3'). Object (bucket_name = 'stackoverflow-41292005', key = 'test.txt'). Metadata)'. Вы должны увидеть: '{'keyname1': 'test1', 'keyname2': 'test2'}'. (Ваш пользователь IAM должен иметь права на операции s3: *, конечно). –

+0

, что не работает для меня. metadata = {}. Как я уже говорил выше, метаданные пустые. Я схватил его по-другому. Даже тогда, если вы попытаетесь сохранить тип контента, он изменится (см. Вопрос редактирования). –

Смежные вопросы