最近感觉光阴似箭,直接简单介绍最近做的事情吧,详细如下。
- 26号,完成图片(特点是pkl格式)读取与显示功能(web端)。
- 27号,上午开会:各位老师说明来年计划,我也计划要做用户行为的F值与介绍部分内容并投稿,然后以此处理增加权重挑选和自适应裁剪并投稿,最后是选择用户与异常在时间上的关系,最后得到综合诊断报告以及开题工作。
- 28号,增加中文支持,下午与张钦讨论关联分析相关内容。
- 29号,实现全主机检测,同时发现主成分分析的基线模型不过原点,因此可以检测漏报的异常情况。
- 30号,下午何荣老师演讲。
图片读取程序
1. 介绍
最近需要用到一个简单功能,即读取图片并显示。当然,读取普通图片并显示本身没有什么难度,
计算机本身图片处理软件既可以打开,但是我平常编程使用python
进行数据处理,然后使用matplotlib
进行绘图并保存,为了保证保存的图片保留原始数据的所有信息,我一般使用pickle
将图片保存成为
.pkl
的二进制文件,在这种情况下,必须使用python
里面的pickle
包恢复文件才能显示。
2. 使用flask
flask是一个比较流行的Web框架,它通过渲染
- GET /:首页,返回templates文件夹里面的页面
- POST: 提交数据后进行处理并返回的页面
为了使得返回可以渲染的html
页面显示数据,需要将主页实现好,并在里面加入需要变化文字的模板变量即可,flask
内部支持jinja2模板。复杂的使用方式请直接看其文档,我这里仅仅使用两个简单的变量用来显示图片和简单提示,具体页面代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>显示图片的小程序</title>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css">
</head>
<body>
<h1 class="animated infinite pulse delay-2s" align="center">选择pkl文件(matplotlib生成的)并显示该图片的程序~</h1>
<form method="POST" action="" enctype="multipart/form-data">
<input id = "choose-pic-file-button" type="file" name='TheFile'>
<input type="submit" value="Submit">
</form>
<div id="image-show" style="border: 1px solid #ccc;
width: 100%;
height: 500px;
background-size: contain;
background-repeat: no-repeat;
background-position: center center;
background-image :;"></div>
<p id="info"></p>
</body>
</html>
其中使用了渲染图片显示的`base64`格式的文件的,而
用来显示提示消息的。
3. 读取和显示图片
3.1 失败方案探索(如想直接看结果请直接跳到3.2小节)
使用一个函数,用来根据文件名返回浏览器background-image对应的值可以显示的base64编码字符串
def picToBase(fileName): #根据文件名返回浏览器background-image对应的值可以显示的base64编码字符串
with open(fileName,'rb') as f:
base64_data = base64.b64encode(f.read())
picData = 'url(data:image/jpg;base64,' + base64_data.__str__()[2:-1] + ')'
return picData
结果发现直接通过路径不行,因为网页不会发生客户端的真实路径!
3.2 正确方案
根据上述的失败描述,得出为了能将图片在后端处理,必须将结果得到的结论,因此需要使用web的post请求,将图片的数据得到,因此直接在网页端加上submit
类型的<input>
标签即可。
为了能够让matplotlib
显示中文,需要一个函数:
def supportChinese(): #增加支持中文的设定
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
之后既可以单用户点击提交按钮时在post里面实现将返回数据处理渲染到网页上的效果:
@app.route('/', methods=['POST'])
def postHome():
print('send the POST request!')
# print(request.form)
# print(request.files['TheFile'])
tem = request.files['TheFile'] #得到表单提交的文件
# f = request.files['TheFile'].read() #bytes数据
data = None
messages = None
if tem.content_type.startswith('image/'): #如果是图片
base64_data = base64.b64encode(tem.read())
data = 'url(data:image/jpg;base64,' + base64_data.__str__()[2:-1] + ')'
messages = '该图片是'+tem.content_type+'类型,已经显示出来了!'
elif tem.filename.endswith('.pkl'): #如果是pkl文件
supportChinese()
ax = pickle.load(tem)
data = None
with open('tem.jpg','wb') as f:
plt.savefig(f)
with open('tem.jpg', 'rb') as f:
base64_data = base64.b64encode(f.read())
data = 'url(data:image/jpg;base64,' + base64_data.__str__()[2:-1] + ')'
messages = '该图片是' + tem.content_type + '类型,已经显示出来了!'
else: #其他无法处理情况
data = 'tem' # picToBase(fileName)
messages = '很抱歉,您提交的文件类型暂不支持!'
return render_template('home.html', data=data, messages=messages)
最后,所有代码的具体实现在:https://github.com/Dongzhixiao/Python_Exercise/tree/master/picReaderAndSaverBaseWeb