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格式,避免序列化异常。
- 客户端:
- 将响应流转为字符串后解析为JSON数组,提取每个图片的Base64编码。
- 用
base64Decode将字符串转为字节数组,可直接传入Image.memory实现展示。 - 通过
path_provider获取应用合法存储目录,将字节写入文件完成本地保存。
内容的提问来源于stack exchange,提问作者Ted Zhai
相关产品推荐
相关产品推荐

