11底

2018/11/26 光阴似箭

Posted by WangXiaoDong on November 26, 2018
    最近感觉光阴似箭,直接简单介绍最近做的事情吧,详细如下。
  • 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