如何解决使用Flutter将http后请求包含图像发送到Flask API
我已经在CIFAR10数据集中训练了CNN(占位符,稍后将替换为其他模型),并将该模型集成到flask API中。该API托管在Heroku上,我现在想使用Flutter / Dart在手机上拍照,将其发送到Flask API,在其上运行经过训练的模型,然后返回预测。
使用python,我可以轻松地向我的API发出发布请求并返回预测。这是我的简单python代码:
import requests
import json
img = open('some-picture.jpg','rb')
files = {'image': img}
response = requests.post("url_to_api",files=files)
print(response.text)
我已经很长时间没有使用Flutter / Dart了,我发现发出htpp请求的过程比在python中复杂一些。 有人可以给我一些指针或代码,让我用相机拍照,将其上传到我的API并将响应存储在变量中吗?这是我的flask API的(简化)python代码:
from flask import Flask,request
import os
import numpy as np
from PIL import Image
from tensorflow import keras
app = Flask(__name__)
app.config["DEBUG"] = True
model = keras.models.load_model('cifar10_cnn.h5')
labels = ["Airplane","Automobile","Bird","Cat","Deer","Dog","Frog","Horse","Ship","Truck"]
@app.route('/',methods=["POST"])
def predict():
# stuff not relevant to question,left out for conciseness #
file = request.files['image']
image = Image.open(file).resize((32,32))
image = np.array(image)
image = image / 255
image = image.reshape(-1,32,3)
predictions = model.predict([image])
index = np.argmax(predictions)
results = {'Prediction:': labels[index]}
return results
if __name__ == '__main__':
app.run()
到目前为止,我知道Multipart文件似乎很可行,而且Dio包可能值得研究。如果能提供更多提示或代码,我将不胜感激。
解决方法
您可能已经知道如何从图库/相机中选择图像(例如,使用image_picker
库)。使用该选择器的结果填充一个File image;
之类的全局变量。这可能很简单:
import 'dart:io';
import 'package:image_picker/image_picker.dart';
class _MyHomePageState extends State<MyHomePage> {
File image;
final picker = ImagePicker();
pickImageFromGallery(ImageSource source) async {
final image = await picker.getImage(source: source);
setState(() {
this.image = File(image.path);
});
}
}
(更改ImageSource source
使其符合您的需求:相机或图库)
然后,您可以将该文件上传到api。
使用http
库:
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
class _MyHomePageState extends State<MyHomePage> {
doUpload(){
var request = http.MultipartRequest(
'POST',Uri.parse("url_to_api"),);
Map<String,String> headers = {"Content-type": "multipart/form-data"};
request.files.add(
http.MultipartFile(
'image',image.readAsBytes().asStream(),image.lengthSync(),filename: "filename",contentType: MediaType('image','jpeg'),),);
request.headers.addAll(headers);
print("request: " + request.toString());
request.send().then((value) => print(value.statusCode));
}
}
对于这些库中的每一个,都必须将它们作为依赖项添加到flutter项目的pubspec.yaml
中:
cupertino_icons: ^0.1.3
http: ^0.12.2
image_picker: ^0.6.7
,
我对Django和Flutter做过类似的工作。我使用image_picker选择图像,并使用dio上传图像。
这是上传功能:
_upLoadImage(File image) async {
setState(() {
loadingdone = false;
});
String path = image.path;
var name = path.substring(path.lastIndexOf("/") + 1,path.length);
var suffix = name.substring(name.lastIndexOf(".") + 1,name.length);
FormData formData = FormData.fromMap({
"img": await MultipartFile.fromFile(path,filename: name)
});
Dio dio = new Dio();
var respone = await dio.post<String>("http://192.168.1.104:8000/uploadImg/",data: formData);
if (respone.statusCode == 200) {
Fluttertoast.showToast(
msg: 'Done!',gravity: ToastGravity.BOTTOM,textColor: Colors.grey);
setState(() {
_label = jsonDecode(respone.data.toString())['label'];
_score = jsonDecode(respone.data.toString())['score'];
loadingdone = true;
});
}
}
选择图片后运行上传功能:
Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
_upLoadImage(image);
setState(() {
_image = image;
});
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。