通过Flask发送二进制列表

时间:2018-10-14 13:05:10

标签: python python-3.x flask

我正在使用Flask编写API,在其中我通过POST接收图像,并将其拆分为多个图块,并希望将它们作为响应发送回去。

我首先获取图像,然后使用Image作为PIL对象打开它,然后通过裁剪操作创建图块。 到目前为止,一切都很好。

现在,我想将它们作为二进制文件发送,以便按照here的说明将它们显示在前面(尽管我不确定这是否是最好的方法)。 我尝试使用flask.jsonify,它告诉我bytes对象不可json序列化。

因此,如何发送创建的图块列表?

我的路线如下:

import io
from flask import request
from PIL import Image
from . import app


@app.route("/map/tileset/prepare", methods=['POST'])
def prepare_tileset():
    image_source = request.files['image']
    width = int(request.form['tileWidth'])
    height = int(request.form['tileHeight'])

    data = image_source.stream.read()
    image_descriptor = io.BytesIO(data)
    original = Image.open(image_descriptor)

    tiles = []
    for i in range(original.width // width):
        for j in range(original.height // height):
            rect = ((width)*i, (height)*j, (width)*(i+1) - 1, (height)*(j+1) - 1)
            tile = original.crop(rect)

            # It works until here, but I don't know what to do after

            tiles.append(tile)

    return tiles

1 个答案:

答案 0 :(得分:1)

JSON不直接支持二进制数据。 JSON支持字符串,但是它们就像Python中的unicode字符串一样。

通常,base64编码用于通过JSON传输二进制数据。

一种可能的解决方案是使用数据URL:

import flask, io
from base64 import b64encode

@app.route("/map/tileset/prepare", methods=['POST'])
def prepare_tileset():
    # ...

    tiles = []
    for i in range(original.width // width):
        for j in range(original.height // height):
            rect = ((width)*i, (height)*j, (width)*(i+1) - 1, (height)*(j+1) - 1)
            tile = original.crop(rect)

            # BytesIO is an in-memory file abstraction so we don't have
            # to write any actual files to disk
            f = io.BytesIO()
            tile.save(f,"PNG")
            tile_png_bytes = f.getvalue()

            tile_png_b64 = b64encode(tile_png_bytes).decode()
            # remove newlines
            tile_png_b64 = tile_png_b64.replace('\n', '')
            tile_data_url = 'data:image/png;base64,' + tile_png_b64

            tiles.append(tile_data_url)

    return flask.jsonify(tiles)

未经测试,希望它能起作用:)