Как получить изображение во flutter из flask api

#python #numpy #flutter #flask

#python #numpy #flutter #flask

Вопрос:

У меня есть post-запрос в Flask, который принимает файл изображения, и я хочу вернуть другое изображение, чтобы извлечь его во Flutter и вывести на экран.

Во Flutter я могу отправить изображение через post-запрос, но я не знаю, как получить изображение и вывести его на экран.

Я знаю, что могу сохранить изображение в статической папке в Flask и получить URL-адрес из Flutter, и это работает, но я думаю, что это слишком неэффективно для того, что я делаю. Итак, я хочу отправить изображение напрямую, не сохраняя его.

Это была моя последняя попытка, но она не сработала.

 @app.route("/send-image", methods=['POST'])
def send_image():
    if request.method == 'POST':

        user_image = request.files["image"]
        image = cv2.imdecode(np.frombuffer(
            user_image.read(), np.uint8), cv2.IMREAD_COLOR)

        #data is a NumPy array returned by the predict function. This numpy array it's an image
        data = predict(image)

        data_object = {}
        data = data.reshape(data.shape[0], data.shape[1], 1)
        data2 = array_to_img(data)

        b = BytesIO()
        data2.save(b, format="jpeg")
        b.seek(0)

        data_object["img"] = str(b.read())
        return json.dumps(data_object)
  

Здесь я вернул Uint8List, потому что прочитал в Интернете, что я могу поместить это в Image.memory(), чтобы вывести изображение на экран.

 Future<Uint8List> makePrediction(File photo) async {
    const url = "http://192.168.0.11:5000/send-image";
    try {
      FormData data = new FormData.fromMap({
        "image": await MultipartFile.fromFile(photo.path),
      });
      final response = await dio.post(url, data: data);

      String jsonResponse = json.decode(response.data)["img"].toString();
      List<int> bytes =
          utf8.encode(jsonResponse.substring(2, jsonResponse.length - 1));

      Uint8List dataResponse = Uint8List.fromList(bytes);

      return dataResponse;
    } catch (error) {
      print("ERRORRR: "   error.toString());
    } 
  }
  

Извините, если то, что я здесь сделал, не имеет смысла, но после того, как я перепробовал много вещей, я не думал должным образом.
Мне действительно нужна ваша помощь

Ответ №1:

Вы можете преобразовать изображение в base64 и отобразить его с помощью Flutter.

На сервере:

 import base64
...
data_object["img"] = base64.b64encode(b.read()).decode('ascii')
...
  

На клиенте:

 ...
String imageStr = json.decode(response.data)["img"].toString();
Image.memory(base64Decode(imageStr));
...
  

Проблема с вашим серверным кодом заключается в том, что он пытается принудительно использовать объект bytes to str с помощью функции str() .

Однако в Python 3 bytes.__repr__ вызывается с помощью, str() поскольку bytes.__str__ не определено. Это приводит к чему-то вроде этого:

 str(b'xf9xf3') == "b'\xf9\xf3'"
  

Это делает ответ JSON похожим:

 {"img": "b'\xf9\xf3'"}
  

Без написания специального анализатора вы не сможете прочитать этот формат данных изображения во Flutter. Однако base64 — это хорошо известный формат кодирования двоичных данных, и у нас есть анализатор base64Decode во Flutter.

Комментарии:

1. @Carb2750 Я внес некоторые правки в код на стороне сервера, поскольку я не тестировал код. Однако, похоже, вы уже разобрались с этим.