You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何解析响应体中的图片?实现处理后图片转File列表

问题分析与解决方案

1. 服务端核心问题:直接返回PIL Image对象无法被序列化

FastAPI无法直接处理PIL的Image对象序列化,必须将处理后的图片转换为可传输的格式(如Base64编码字符串),否则会导致响应异常,客户端无法解析。

修改后的服务端代码

from fastapi import FastAPI, UploadFile
from typing_extensions import List
from PIL import Image
import io
import base64

app = FastAPI()

@app.post('/process')
async def upload_images(files: List[UploadFile]):
    processed_images_base64 = []
    for f in files:
        contents = await f.read()
        image = Image.open(io.BytesIO(contents))
        
        # 示例处理:翻转+缩放图片,可替换为你的业务逻辑
        image = image.transpose(Image.FLIP_LEFT_RIGHT)
        image = image.resize((200, 200))
        
        # 将图片转为Base64编码字符串
        img_byte_arr = io.BytesIO()
        image.save(img_byte_arr, format='JPEG')  # 可根据需求改为PNG
        img_byte_arr = img_byte_arr.getvalue()
        img_base64 = base64.b64encode(img_byte_arr).decode('utf-8')
        
        processed_images_base64.append(img_base64)
    
    return processed_images_base64

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

2. Flutter客户端:解析响应并实现保存/展示

客户端需要将服务端返回的Base64字符串列表解码为字节,再转换为File保存到本地,或直接用Image.memory组件展示。

修改后的客户端代码

import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';

void main() async {
  const String url = "http://localhost:8000/process";
  var request = http.MultipartRequest("POST", Uri.parse(url));

  // 添加本地图片,替换为你的实际图片路径
  var image = File('image.jpg');
  request.files.add(await http.MultipartFile.fromPath('files', image.path));
  request.files.add(await http.MultipartFile.fromPath('files', image.path));

  final response = await request.send();
  if (response.statusCode == 200) {
    // 解析响应为Base64字符串列表
    String responseStr = await response.stream.bytesToString();
    List<String> imgBase64List = List<String>.from(jsonDecode(responseStr));

    // 保存图片到本地
    List<File> savedFiles = [];
    Directory appDir = await getApplicationDocumentsDirectory();
    for (int i = 0; i < imgBase64List.length; i++) {
      Uint8List imgBytes = base64Decode(imgBase64List[i]);
      File file = File('${appDir.path}/processed_image_$i.jpg');
      await file.writeAsBytes(imgBytes);
      savedFiles.add(file);
      print('图片已保存:${file.path}');
    }

    // 如需在界面展示,可使用Image.memory(base64Decode(imgBase64List[0]))
  } else {
    print('请求失败:${response.statusCode}');
  }
  exit(0);
}

关键说明

  • 服务端:通过Base64编码将图片转为字符串,确保响应为标准JSON格式,避免序列化异常。
  • 客户端:
    1. 将响应流转为字符串后解析为JSON数组,提取每个图片的Base64编码。
    2. 用base64Decode将字符串转为字节数组,可直接传入Image.memory实现展示。
    3. 通过path_provider获取应用合法存储目录,将字节写入文件完成本地保存。

内容的提问来源于stack exchange,提问作者Ted Zhai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 23:43:28