欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

【后端过程记录】用flask搭建服务器作后端接收数据 将base64字符串码解码为可读取文件 载入训练好的模型进行预测

发布时间:2024/9/30 编程问答 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 【后端过程记录】用flask搭建服务器作后端接收数据 将base64字符串码解码为可读取文件 载入训练好的模型进行预测 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

因为项目的原因了解到有一个python的flask框架,查了一下:
关于前端图片上传的canvas:
如下元素

<canvas id="canvas" width="5" height="5"></canvas>

可以用这样的方式获取一个 data-URL

var canvas = document.getElementById("canvas"); var dataURL = canvas.toDataURL(); console.log(dataURL);

// “data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNby
// blAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC”
设置jpegs图片的质量

var fullQuality = canvas.toDataURL("image/jpeg", 1.0); // data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...9oADAMBAAIRAxEAPwD/AD/6AP/Z" var mediumQuality = canvas.toDataURL("image/jpeg", 0.5); var lowQuality = canvas.toDataURL("image/jpeg", 0.1);

getContext() 方法返回一个用于在画布上绘图的环境。

语法
Canvas.getContext(contextID)
参数
参数 contextID 指定了您想要在画布上绘制的类型。当前唯一的合法值是 “2d”,它指定了二维绘图,并且导致这个方法返回一个环境对象,该对象导出一个二维绘图 API。

提示:在未来,如果 < canvas> 标签扩展到支持 3D 绘图,getContext() 方法可能允许传递一个 “3d” 字符串参数。

返回值
一个 CanvasRenderingContext2D 对象,使用它可以绘制到 Canvas 元素中。
后端:
首先pip install Flask
然后新建文件:

from flask import Flask,make_response, jsonifyfrom multiprocessing import Process# 配置全局app app = Flask(__name__) # 导入index中定义的所有函数 #from autotrade.server.index import *def run_index():# 启动web服务器,使用多线程方式,接收所有http请求app.run(host='0.0.0.0', port=5000, threaded=True)def make_new_response(data):res = make_response(jsonify({'code': 0, 'data': data}))res.headers['Access-Control-Allow-Origin'] = '*'res.headers['Access-Control-Allow-Method'] = '*'res.headers['Access-Control-Allow-Headers'] = '*'return res@app.route('/') def hello_world():return {'hello': 'world!'}@app.route("/test") def test():res = "{'no':'dddd'}"return make_new_response(res)if __name__ == "__main__":app.run(debug=True)


打开浏览器:

向flask后端发请求接收图片:(点击按钮触发事件)
flask:

from flask import Flask,make_response, jsonify from flask_cors import CORS import socket import threading import json import os from io import BytesIO from multiprocessing import Process import io from PIL import Image # 配置全局app app = Flask(__name__) # 导入index中定义的所有函数 #from autotrade.server.index import * def main():# 创建服务器套接字serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 获取本地主机名称host = socket.gethostname()# 设置一个端口port = 5000# 将套接字与本地主机和端口绑定serversocket.bind((host, port))# 设置监听最大连接数serversocket.listen(5)# 获取本地服务器的连接信息myaddr = serversocket.getsockname()print("服务器地址:%s" % str(myaddr))# 循环等待接受客户端信息while True:# 获取一个客户端连接clientsocket, addr = serversocket.accept()print("连接地址:%s" % str(addr))try:t = ServerThreading(clientsocket) # 为每一个请求开启一个处理线程t.start()passexcept Exception as identifier:print(identifier)passpassserversocket.close()passdef run_index():# 启动web服务器,使用多线程方式,接收所有http请求app.run(host='0.0.0.0', port=5000, threaded=True)CORS(app, resources=r'/*', supports_credentials=True)basedir = os.path.abspath(os.path.dirname(__file__))@app.route('/getPic',methods=['GET', 'POST']) def findpic():img_url = basedir+'/data/tt/b/b_1.png'print(img_url)with open(img_url, 'rb') as f:a = f.read()'''对读取的图片进行处理'''img_stream = io.BytesIO(a)img = Image.open(img_stream)imgByteArr = io.BytesIO()img.save(imgByteArr,format='PNG')imgByteArr = imgByteArr.getvalue()print(imgByteArr)return imgByteArrif __name__ == "__main__":app.run(debug=True)

注意:Python在内存中读写数据,用到的模块是StringIO和BytesIO,当为StringIO时getvalue()方法用于获得写入后的str。StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。可以用一个bytes初始化BytesIO,然后,像读文件一样读取:

>>> from io import BytesIO >>> f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87') >>> f.read() b'\xe4\xb8\xad\xe6\x96\x87'

BytesIO实现了在内存中读写bytes。

vue代码:

<button @click="getPic">获取图片</button><img :src="picurl" alt="beachball" /> data () {return {picurl: "",}},methods: {getPic() {var that = this;this.$axios.get('http://127.0.0.1:5000/getPic',{responseType: "arraybuffer",}).then(function (response) {that.picurl ="data:image/jpeg;base64," + that.arrayBufferToBase64(response.data);});},arrayBufferToBase64(buffer) {//第一步,将ArrayBuffer转为二进制字符串var binary = "";var bytes = new Uint8Array(buffer);var len = bytes.byteLength;for (var i = 0; i < len; i++) {binary += String.fromCharCode(bytes[i]);}//将二进制字符串转为base64字符串return window.btoa(binary);}, }

点击按钮后:

后端的显示:

图片传给后端

捣鼓了半天终于把图片传给后端了,不过暂时用的java测试。中途遇到无数次cannot read property xxx xxx is not defined,怀疑是自己哪些代码莫名出了问题,因为canvas是getelementbyid,所以如果写的是ref的话是获取不到的,然后注释掉了一堆代码,结果:


后端的响应:

flask获取图片数据:

flask获取参数方式:

request.form.get(“key”, type=str, default=None) 获取表单数据

request.args.get(“key”) 获取get请求参数

request.values.get(“key”) 获取所有参数

import base64 img1='E:/nsfw_tensorflow/corpus/weibocore_WBC_IMAGE_DATA_SOURCE_6521.jpg'pimg=open(img1, 'rb').read()print(pimg)# base64图片加密 result = base64.b64encode(pimg)print(result)# 再把加密后的结果解码 temp = base64.b64decode(result)print(temp)

现在出现一个问题,从前端发送图片之后后端接收到的data一直是str类型,不知道怎么取出来:

@app.route('/getpic', methods=['POST']) def getpic():data = flask.request.get_data().decode('utf-8')data = json.loads(data)data_b64 = data["data"]print(type(data_b64))


修改:

def getpic():data = json.loads(flask.request.get_data("data"))data_64 = str.encode(data['data'])print(type(data_64))print(data_64)

得到类型为bytes.
前端去掉base64前面的前缀:

var image = this.thisCancas.toDataURL("image/png").split('base64,')[1];

搞了好久试了好多方法终于把前端的图片base码解出来了!!!!!!激动
后端的代码:

def decode_base64(data):"""Decode base64, padding being optional.:param data: Base64 data as an ASCII byte string:returns: The decoded byte string."""missing_padding = len(data) % 4if missing_padding != 0:data += b'='* (4 - missing_padding)# return base64.decodestring(data)return base64.b64decode(data)#上面这个函数用来解码base64字符串 @app.route('/getpic', methods=['POST']) def getpic():data = json.loads(flask.request.get_data("data"))data_64 = str.encode(data['data'])print(type(data_64))#print(data_64)print('------------------------')print(str(data_64, 'utf8')) #用这个方法去掉base64码前面b'xxx'的bimgdata = decode_base64(data_64)file = open('1.jpg', 'wb')file.write(imgdata)file.close()

其中注意前端发送的数据也经过了处理,使得去掉了img/jpeg前缀

现在载入模型进行拍照预测:
附上关键的代码:

import torch from torchvision import transforms def run_index():# 启动web服务器,使用多线程方式,接收所有http请求app.run(host='0.0.0.0', port=5000, threaded=True) def decode_base64(data):"""Decode base64, padding being optional.:param data: Base64 data as an ASCII byte string:returns: The decoded byte string."""missing_padding = len(data) % 4if missing_padding != 0:data += b'='* (4 - missing_padding)# return base64.decodestring(data)return base64.b64decode(data) transform=transforms.Compose([transforms.Resize(224),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean=[0.485,0.456,0.406],std=[0.229,0.224,0.225])])CORS(app, resources=r'/*', supports_credentials=True) @app.route('/getpic', methods=['POST']) def getpic():data = json.loads(flask.request.get_data("data"))data_64 = str.encode(data['data'])print(type(data_64))#print(data_64)print('------------------------')print(str(data_64, 'utf8'))imgdata = decode_base64(data_64)file = open('1.jpg', 'wb')file.write(imgdata)file.close()image = Image.open(r"1.jpg").convert('RGB')image = transform(image).unsqueeze(0)modelme = torch.load('modefresnet.pkl')modelme.eval()outputs = modelme(image)_, predict = torch.max(outputs.data, 1)for j in range(image.size()[0]):print('predicted: {}'.format(class_names[predict[j]]))return class_names[predict[j]] if __name__ == "__main__":app.run(debug=True)


试了好多次,几乎都与预测结果相符。
哈哈哈哈哈花了两天弄这个,之前关于图片解码编码一直没弄出来,现在成功了还是挺开心的。

总结

以上是生活随笔为你收集整理的【后端过程记录】用flask搭建服务器作后端接收数据 将base64字符串码解码为可读取文件 载入训练好的模型进行预测的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。