Отправить список двоичных файлов через Flask - PullRequest
0 голосов
/ 14 октября 2018

Я пишу API с Flask, в котором я получаю изображение через POST и делю его на плитки, которые я хочу отправить в ответ.

Сначала я получаю изображение,затем откройте его как Image объект с PIL и создайте плитки из операции обрезки.Пока все хорошо.

Теперь я хотел бы отправить их в виде двоичных файлов, чтобы отобразить их спереди, как объяснено здесь (хотя я не уверен, является ли это лучшимпуть).Я попытался с flask.jsonify, который сказал мне, что объект bytes не является json-serializable.

Поэтому, как я могу отправить список созданных плиток?

Мой маршрутследующим образом:

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 голосов
/ 14 октября 2018

JSON не поддерживает двоичные данные напрямую.JSON поддерживает строки, но они похожи на строки Юникода в Python.

Обычно для передачи двоичных данных через JSON используется кодировка base64.

Одним из возможных решений является использование 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)

Не проверено, надеюсь, что это работает:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...