zoukankan      html  css  js  c++  java
  • Flask使用笔记

    DIP Using Flask

    目的

    制作一个简单的图像处理软件,能够实现基本的图像处理操作。

    DIP

    真正核心的图像处理部分是调库的,python在这方面充分展现了第三方库的强大功能。

    requirements如下

    import numpy as np
    import cv2
    from PIL import Image,ImageEnhance,ImageDraw,ImageFont
    from skimage import io,color,transform,img_as_float,img_as_ubyte,img_as_uint
    from skimage.exposure import histogram,adjust_gamma,adjust_log,adjust_sigmoid,equalize_hist
    import matplotlib.pyplot as plt
    

    GUI

    在这个项目中,我的主要工作就是GUI,所以可谈的就比较多了。作为我的第一个独立创作的flask应用,比较上心。

    $ tree
    ├─.vscode
    ├─static
    │  ├─css
    │  ├─Image
    │  └─js
    ├─templates
    └─__pycache__
    

    templates下是html的模板。对于flask来说,需要渲染的模板通过render_templates调用,这样可以极大的减少前端代码的重复率,提高开发效率。

    对于这个项目来说,base.html下有3个扩展,index.htmlbasic.htmldip.html。这三个页面都继承自base.html

    app.py如下:

    from flask import Flask, render_template, url_for, request, flash, redirect
    from flask_bootstrap import Bootstrap
    from forms import *
    import os
    from werkzeug.utils import secure_filename
    from ImageOP import ImageProcess
    import numpy as np
    import pyperclip
    
    app = Flask(__name__)
    basedir = os.path.abspath(os.path.dirname(__file__))
    bootstrap = Bootstrap(app)
    app.config["SECRET_KEY"] = "A-VERY-LONG-SECRET-KEY"
    filename = ""
    iop = ImageProcess()
    
    @app.route("/", methods=["POST", "GET"])
    def index():
        form = UpLoadFileForm()
        global filename
        print("in index")
        if form.validate_on_submit():
            f = form.photo.data
            filename = os.path.join('static/Image', secure_filename(f.filename))
            f.save(os.path.join(
                basedir, filename
            ))
            print(filename)
            try:
                iop.PhotoOpen(filename, change=True)
                flash("上传成功: " + filename, category="success")
            # return redirect(url_for('index'))
            except Exception as e:
                flash("文件打开失败", category="danger")
                flash(e, category="danger")
        if filename == "":
            flash("请打开图片", category="warning")
        if filename:
            iop.PhotoOpen(filename)
        print("index filename", filename)
        return render_template("index.html", upload_file_form=form, filename=filename + "?randomstr=" + str(np.random.rand()))
    
    @app.route("/basic", methods=["POST", "GET"])
    def basic():
        global filename
        if filename == "":
            return redirect(url_for("index"))
        rotate_form = RotateForm()
        if rotate_form.validate_on_submit():
            filename = iop.RotateOP(rotate_form.angle.data)
        if filename:
            iop.PhotoOpen(filename)
        return render_template("basic.html", filename=filename + "?randomstr=" + str(np.random.rand()), rotate_form=rotate_form)
    
    @app.route("/dip", methods=["POST", "GET"])
    def dip():
        global filename
        if filename == "":
            return redirect(url_for("index"))
        sharpen_form = SharpenForm()
        if sharpen_form.validate_on_submit():
            if sharpen_form.operation.data == 0:
                filename = iop.BSCenhance(sharp_factor=sharpen_form.factor.data, choice="sharp")
            elif sharpen_form.operation.data == 1:
                filename = iop.BSCenhance(bright_factor=sharpen_form.factor.data, choice="contrast")
            else:
                filename = iop.BSCenhance(contrast_factor=sharpen_form.factor.data, choice="bright")
        filter_form = FilterForm()
        if filter_form.validate_on_submit():
            # filter_form.filtername.data
            arr = ["gaussian", "emboss", "edge", "sharp", "rect"]
            filename = iop.filters(arr[filter_form.filtername.data])
        linear_form = LinearForm()
        if linear_form.validate_on_submit():
            filename = iop.Hist_linear(a=linear_form.slope.data, b=linear_form.bias.data)
        unlinear_form = UnLinearForm()
        if unlinear_form.validate_on_submit():
            if unlinear_form.function.data == 0:
                filename = iop.Hist_gamma(1.2)
            elif unlinear_form.function.data == 1:
                filename = iop.Hist_sigmoid()
            else:
                filename = iop.Hist_log()
        color_space_reverse_form = ColorSpaceReverseForm()
        if color_space_reverse_form.validate_on_submit():
            arr = ['RGB', 'HSV', 'RGB CIE', 'XYZ', 'YUV', 'YIQ', 'YPbPr', 'YCbCr']
            filename = iop.ColorSpaceChange(arr[color_space_reverse_form.toSpace.data])
        if filename:
            iop.PhotoOpen(filename)
        return render_template("dip.html", filename=filename + "?randomstr=" + str(np.random.rand()), 
                        sharpen_form=sharpen_form, filter_form=filter_form, 
                        linear_form=linear_form, unlinear_form=unlinear_form,
                        color_space_reverse_form=color_space_reverse_form)
    
    @app.route("/share", methods=["POST", "GET"])
    def share():
        global filename
        url = "127.0.0.1:5000/" + filename
        pyperclip.copy(url)
        flash("图片已经黏贴到剪切板", category="success")
        return "filename: " + url
    
    @app.route("/equalization", methods=["POST", "GET"])
    def equalization():
        global filename
        filename = iop.Hist_equalize()
        return redirect(url_for("dip"))
    
    @app.route("/smooth", methods=["POST", "GET"])
    def smooth():
        global filename
        filename = iop.filters("rect")
        return "smooth over py"
    
    @app.route("/histogram", methods=['POST', 'GET'])
    def histogram():
        print("in histogram")
        hist = iop.Hist()
        return hist + "?randomstr=" + str(np.random.rand())
    
    @app.route("/FFTDCT", methods=["POST", "GET"])
    def FFTDCT():
        print("in fft dct", request.form.get("operation"))
        ret = iop.FftDct(request.form.get("operation"))
        print(ret)
        return ret + "?randomstr=" + str(np.random.rand())
    
    @app.route("/org", methods=["GET"])
    def org():
        global filename
        print(filename)
        filename = iop.orgFile
        print(filename)
        iop.PhotoOpen(filename, change=True)
        return redirect(url_for("index"))
    
    @app.route("/undo", methods=["GET", "POST"])
    def undo():
        global filename
        print(iop.temp)
        if iop.temp <= 1:
            print("here")
            filename = iop.orgFile
            iop.PhotoOpen(iop.orgFile)
            flash("已是最原始操作!", category="warning")
        else:
            iop.temp -= 1
            filename = iop.base_dir + 'temp'+str(iop.temp)+'.'+iop.format
            print("in undo")
            print(filename)
            iop.PhotoOpen(filename)
        return "undo over py"
    
    @app.route("/redo", methods=["GET", "POST"])
    def redo():
        try:
            global filename
            iop.temp += 1
            iop.PhotoOpen(iop.base_dir + 'temp'+str(iop.temp)+'.'+iop.format)
            filename = iop.base_dir + 'temp'+str(iop.temp)+'.'+iop.format
        except:
            iop.temp -= 1
            flash("已经是最新操作!", category="warning")
        return "redo over py"
    
    @app.route("/rotate1")
    def rotate1():
        global filename
        filename = iop.RotateOP(90)
        return redirect(url_for("basic"))
    
    @app.route("/rotate2")
    def rotate2():
        global filename
        filename = iop.RotateOP(-90)
        return redirect(url_for("basic"))
    
    if __name__ == "__main__":
        app.run(debug=True, host="0.0.0.0", port="5000")
    

    flask

    在flask中,有一个常用的语句@app.route(),这个方法可以将重定向的网页调用下面的函数,这样就为html间的通信提供了有力的工具。
    在javascript中,可以使用$ajax(settings)来对python进行访问。

    $ajax({
    	url: "127.0.0.1:5000/",
    	type: "POST",
    	data: {data: none},
    	dataType: html,
    	success: function(data, status) {
    		console.log(status);
    	}
    });
    

    在python中,使用flask提供的url_for

    @app.route("/about")
    def about():
        return url_for("index")
    

    总结

    学习flask,让我了解了不少前端知识,我也第一次明白什么是框架,为什么要用框架。

    之前曾用纯粹的javascript作为控制,尝试过一个“别踩白块”的实验,后来自己写了一个简单的俄罗斯方块。虽说使用同一种语言既控制前端又控制逻辑,应该是比较方便的,但是我在写方块的旋转和移动的时候,明显觉得对javascript的不适,感觉它不像python、PHP那样,想如果能用其他面向对象的Language来写更复杂的算法就好了。

    事实上,python用户如此庞大,必然有与js交流的方法。

    • flask是python的前端框架,引入flask极大简化了applications of python的开发周期。我曾经很不理解为什么要用框架,直接写不是更灵活么?大二的时候,曾经参与tjy基金会网站的项目,只学过一点MySQL的我就去搞数据库了,负责前端开发的java学长在做完前端之后还来帮SQL实战不来的我们,我就很佩服,那是第一次体会到用框架的方便和高效。
    • flask能够模板化Bootstrap3,相比以前暴力撸html,Bootstrap提供了更加美观、强大、功能完善和安全的界面,而且不会牺牲灵活性。
    • flask对数据库也是很友好的。这学期有一个课程项目,要求用Unity3D制作一个甲烷气体浓度检测仪的使用教程,其中用来临时存储气体浓度数据都是放在.txt里,包括所有以前的课程项目,都是用临时的文本存储,现在想想感觉自己弱爆了……
    • 所有的逻辑都在python内部进行啦!机器学习的模型在flask里面被调用就完了,很省事嘛!

    项目源代码

    Github地址

    一个人没有梦想,和咸鱼有什么区别!
  • 相关阅读:
    批量新增百万条数据 十百万条数据
    sqlserver 组内排序
    EF ++属性会更新实体
    Entity Framework Core: A second operation started on this context before a previous operation completed
    abp Cannot access a disposed object. A common cause of this error is disposing
    abp xunit Can not register IHostingEnvironment. It should be a non-abstract class. If not, it should be registered before.”
    hangfire enqueued but not processing(hangfire 定时任务入队列但不执行)
    EF 更新实体 The instance of entity type 'BabyEvent' cannot be tracked because another instance
    datatable to entiy list 不支持可空类型和枚举类型
    webapi 设置不显示接口到swaggerUI
  • 原文地址:https://www.cnblogs.com/TABball/p/12726943.html
Copyright © 2011-2022 走看看