使用 Python 解析包含来自 AWS Lambda 的图像的 Base64 编码数据

tmo*_*tmo 5 python base64 image multipart aws-lambda

我有一个 Lambda 函数设置,其中的POST方法应该能够接收多格式数据形式的图像、加载图像、执行一些计算并返回一个简单的数字数组。Lambda 函数位于 API 网关后面,并启用 Lambda 代理集成并multipart/form-data设置为二进制媒体类型。

但是,我似乎无法弄清楚如何解析从 AWS Lambda 返回的多格式数据。

其中event['body']包含我无法在此处发布的 Base64 编码数据,因为它占用了太多空间。

我使用以下代码片段来解析多表单数据:

from requests_toolbelt.multipart import decoder
multipart_string = base64.b64decode(body)
content_type = data['event']['headers']['Content-Type']
multipart_data = decoder.MultipartDecoder(multipart_string, content_type)
Run Code Online (Sandbox Code Playgroud)

哪里。content_type'multipart/form-data; boundary=--------------------------881952313555430391739156'

运行multipart_data像这样的组件..

for part in multipart_data.parts:
    print(part.content)
    print(part.headers)
Run Code Online (Sandbox Code Playgroud)

给出这个。内容(太长,无法发布)如下所示:

b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\ ... x00\x7f\xff\xd9'
Run Code Online (Sandbox Code Playgroud)

和标题:

{b'Content-Disposition': b'form-data; name="image"; filename="8281460-3x2-700x467.jpg"', b'Content-Type': b'image/jpeg'}
Run Code Online (Sandbox Code Playgroud)

但是,我仍然不清楚a ) 内容的哪一部分是实际图像?b)如何提取图像,例如将其PIL放入Image.open


补充信息:

这是我用来发布图像并返回事件数据的小型 Flask 应用程序:

import json

from flask import Flask, request 

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def hello(event, context):

    response = {
        "statusCode": 200,
        "event": event
    }

    return {
        "body": json.dumps(response),
    }
Run Code Online (Sandbox Code Playgroud)

这是 POSTMAN 请求的 Python 代码:

import requests

url = "url-to-lambda-function"

payload = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image\"; filename=\"8281460-3x2-700x467.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"
headers = {
    'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
    'User-Agent': "PostmanRuntime/7.18.0",
    'Accept': "*/*",
    'Cache-Control': "no-cache",
    'Content-Type': "multipart/form-data; boundary=--------------------------881952313555430391739156",
    'Accept-Encoding': "gzip, deflate",
    'Content-Length': "30417",
    'Connection': "keep-alive",
    'cache-control': "no-cache"
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
Run Code Online (Sandbox Code Playgroud)

tmo*_*tmo 5

对于来到这里的任何人,这就是我最终解决它的方法:

    body = event["body"]

    content_type = event["headers"]["Content-Type"]

    body_dec = base64.b64decode(body)

    multipart_data = decoder.MultipartDecoder(body_dec, content_type)

    binary_content = []

    for part in multipart_data.parts:
        binary_content.append(part.content)

    imageStream = io.BytesIO(binary_content[0])
    imageFile = Image.open(imageStream)
    imageArray = np.array(imageFile) 
Run Code Online (Sandbox Code Playgroud)

这将产生一个您可以使用的数组,因为您对我来说,困难在于理解多部分/表单数据如何再次缝合在一起。