6分钟

任务 3 前端页面展示及功能说明

任务目的

这一步会介绍前端HTML页面的构建,以及页面中的主要功能代码,介绍页面如何与后端进行交互并接收数据。完成这一步的学习后,学员可以理解本实验的前端页面实现,清楚相关原理后,学员可以尝试独立完成类似页面的开发。

任务步骤

1.模板文件代码展示

注:下方的代码已经包含在配置好的项目目录中,此处仅用于功能说明,学员无需再粘贴项目代码。

实验项目中的模板文件为templates/index.html,这一部分的完整代码展示如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>图像质量分析系统</title>
    <!-- 导入jquery,用于作为bootstrap依赖环境 -->
    <script src="https://code.jquery.com/jquery-3.4.1.js"
        crossorigin="anonymous"></script>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet"
        href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
        integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
        crossorigin="anonymous">
    <style type="text/css">
        body {
            width: 80%;
            margin: 2.5rem auto 0;
            position: relative;
            text-align: center;
            background-color: #1d212c;
        }  
        h1 {
            text-align: center;
            color: #fff;
        }
        .body_container {
            border: 2px solid #0078b6;
            display: inline-block;
            width: 1100px;
            height: 550px;
            margin: 0px auto;
        }
        .header_container > span {
            color: #b5b8be;
            line-height: 60px;
        }
        .left_container {
            width: 35%;
            height: 510px;
            margin: 2% 0 0 2%;
            float: left;
            border: 1px solid #0e6296;
        }
        .img_box {
            padding: 8px;
            /* background-color: lightgray; */
            display: flex;
            justify-content: space-around;
            border-bottom: 1px solid #0e6296;
        }
        .small_img {
            width: 120px;
            height: 120px;
            border: 1px solid #000;
        }
        .big_img {
            height: 360px;
            border: 1px solid #000;
            position: relative;
            margin: 10px;
        }
        .big_img > img {
            position: absolute;
            max-width: 100%;
            max-height: 100%;
            top: -5px;
            left: 0;
            bottom: 0;
            right: 0;
            margin: auto;
        }
        .right_container {
            width: 59.5%;
            height: 510px;
            margin: 2% 2% 0 0;
            float: right;
            text-align: left;
        }
        .upload_container {
            line-height: 40px;
        }
        .upload_label {
            line-height: 40px;
            height: 40px;
            padding: 0 30px;
            color: #fff;
            background-color: #00a4ff;
            cursor: pointer;
            font-weight: normal;
        }
        .upload_label:hover {
            background-color: #0092ee;
        }
        .text_or {
            padding: 0 10px;
            color: #aaadb4;
        }
        .upload_path {
            display: inline-block;
            width: 465px;
            border: 1px solid #aaadb4;
            border-right: 0;
        }
        .upload_path_input {
            display: inline-block;
            width: 356px;
        }
        .upload_path_input > input {
            width: 95%;
            background-color: #1d212c;
            border: none;
            margin-left: 10px;
            color: #fff;
        }
        .upload_path_input > input:focus {
            outline: none;
        }
        .upload_path > a {
            min-width: 90px;
            height: 40px;
            line-height: 40px;
            padding: 13px 37px;
            color: #fff;
            border: 1px solid #00a4ff;
        }
        .upload_path > a:hover {
            background-color: #00a4ff;
            text-decoration: none;
        }
        .upload_tips {
            color: #aaadb4;
        }
        #image_upload {
            display: none;
        }
        .result_container {
            border: 1px solid #0e6296;
            color: #fff;
        }
        .identify_results {
            height: 110px;
        }
        .subtitle {
            padding: 8px;
            background-color: #29273c;
            margin: 0;
            font-size: 16px;
        }
        .response {
            height: 302px;
        }
        .identify_text {
            padding-left: 50px;
            line-height: 34px;
            font-size: 16px;
        }
        .response_text {
            margin-top: -10px;
            padding: 20px 0 0 30px;
            font-size: 15px;
        }
    </style>
</head>
<body onload="initial_func()">
    <div class="header_container">
        <h1>图像质量检测</h1>
        <span>多方面评估图片的视觉质量,输出客观的清晰度评分和主观的美观度评分,可应用于封面选择、相册图片去重、低质量图片过滤等。</span><a href="https://cloud.tencent.com/document/api/865/36899">了解详情</a>
    </div>
    <div class="body_container">
        <div class="left_container">
            <div class="img_box">
                <div class="small_img">
                    <img src="https://accessory-1259416093.cos.ap-chengdu.myqcloud.com/ImageAnalysis/images/demo01.png" alt="demo01" width="100%" height="100%" style="border: 4px solid #00a4ff; z-index: 2">
                </div>
                <div class="small_img">
                    <img src="https://accessory-1259416093.cos.ap-chengdu.myqcloud.com/ImageAnalysis/images/demo02.jpg" alt="demo02" width="100%" height="100%">
                </div>
                <div class="small_img">
                    <img src="https://accessory-1259416093.cos.ap-chengdu.myqcloud.com/ImageAnalysis/images/demo03.png" alt="demo03" width="100%" height="100%">
                </div>
            </div>
            <div id="big_img" class="big_img">
                <img class="show_img" src="https://accessory-1259416093.cos.ap-chengdu.myqcloud.com/ImageAnalysis/images/demo01.png" alt="预览图片">
            </div>
        </div>
        <div class="right_container">
            <div class="upload_container">
                <label class="upload_label" for="image_upload">上传本地图片</label>
                <input type="file" id="image_upload" accept=".png, .jpeg, .jpg" value="上传本地图片">
                <span class="text_or">或</span>
                <form class="upload_path" action="/get_assess_quality" method="post"
                enctype="multipart/form-data">
                    <div class="upload_path_input">
                        <input type="text" class="img_url_path" placeholder="使用网络图片,请粘贴图片URL" name="url_str">
                    </div>
                    <a href="#" class="get_assess_quality">检测</a>
                </form>
                <p class="upload_tips">每次上传的图片大小限制在4M以内,仅支持jpg/png/jpeg格式的图片。</p>
            </div>
            <div class="result_container">
                <div class="identify_results">
                    <p class="subtitle">识别结果</p>
                    <div class="identify_text"></div>
                </div>
                <div class="response">
                    <p class="subtitle">Response</p>
                    <div class="response_text" style="white-space: pre"></div>
                </div>
            </div>
        </div>
    </div>
    <script type="text/javascript">
        var ajax_request;
        $(function(){
            const input = document.querySelector('input');
            // 隐藏上传文件框
            input.style.opacity = 0;
            $('#image_upload').change(function(e) {
                // 上传本地图片
                var _URL = window.URL || window.webkitURL;
                let file, img;
                if ((file = this.files[0])) {
                    img = new Image();
                    img.onload = function() {
                        // 在页面左侧展示图片
                        $('.show_img').attr('src', this.src);
                        $(".small_img").children().css({"border":0, "z-index":1})
                        // 将图片传递给后端处理
                        var img_file = new FormData();
                        img_file.append('img_file', file);
                        // 获取图像分析数据
                        $('.identify_text').html("正在识别中...");
                        $('.response_text').html("     数据获取中...");
                        $.ajax({
                            url: '/get_assess_quality',
                            type: 'post',
                            dataType: 'json',
                            data: img_file,
                            contentType: false,
                            processData: false,
                        })
                        .done(function(res) {
                            handle_res(res)
                        })
                        .fail(function() {
                            $('.identify_text').html("请求失败!")
                            $('.response_text').html("")
                        })
                    };
                    img.src = _URL.createObjectURL(file);
                }
            })

            // 提交图片链接检测图片
            $('.get_assess_quality').click(function(){
                // 获取图片的URL路径
                let img_url_path = document.querySelector('.img_url_path').value
                $(".small_img").children().css({"border":0, "z-index":1})
                if (["png", "jpeg", "jpg"].indexOf(img_url_path.split(".").pop()) == -1 ) {
                    ajax_request.abort()
                    $('.identify_text').html("请输入正确的URL")
                    $('.response_text').html("")
                    return false
                }
                // 将展示图片替换为链接对应图片
                $('.show_img').attr('src', img_url_path)
                let data = {
                    "type": "img_url",
                    "img_url_path": img_url_path,
                }
                get_assess_quality(data)
            })

            $(".small_img").click(function(){
                // 当前选中小图添加边框
                $(".small_img").children().css({"border":0, "z-index":1})
                $(this).children().css({"border":"4px solid #00a4ff", "z-index":2})
                // 将展示图片替换为对应图片
                $('.show_img').attr('src', $(this).children().attr("src"))
                let data = {
                    "type": "img_url",
                    "img_url_path": $(".show_img").attr("src"),
                }
                get_assess_quality(data)
            })
        })

        function handle_res(res) {
            // 处理接收到的数据
            const result_str = "清晰度:" + res.ClarityScore + "<br>" + "美观度:" + res.AestheticScore
            $('.identify_text').html(result_str)
            // 格式化字符串
            html_str = "AssessQuality:<br>" + JSON.stringify(res, null, 4).replace(/\n/g, '<br>').replace(/\s/g, '&nbsp');
            $('.response_text').html(html_str)
            $('.response_text').css("color: #fff; background-color: #1d212c")
        }

        function get_assess_quality(data) {
            // 定义一个函数,用于通过图片路径获取图像分析数据
            $('.identify_text').html("正在识别中...")
            $('.response_text').html("     数据获取中...")
            // 获取图像分析数据
            if (ajax_request != null) {
                // 关闭之前重复的ajax请求
                ajax_request.abort()
                $('.identify_text').html("正在识别中...")
                $('.response_text').html("     数据获取中...")
            }
            ajax_request = $.ajax({
                url: '/get_assess_quality',
                type: 'post',
                dataType: 'json',
                data: data,
            })
            .done(function(res) {
                handle_res(res)
            })
            .fail(function() {
                $('.identify_text').html("请求失败!")
                $('.response_text').html("")
            })
        }

        window.onload = function initial_func() {
            let data = {
                "type": "img_url",
                "img_url_path": $(".show_img").attr("src"),
            }
            get_assess_quality(data)
        }
    </script>
</body>
</html>

下面将会具体介绍模板文件中的主要代码及其功能。

2.模板文件代码详解

(1)模板文件结构说明。

由于本实验中涉及的前端代码较少,所以实验中的所有前端代码均写在了文件index.html中。其中<style></style>标签中的代码对应页面的CSS样式,<body></body>标签中上半部分的代码对应可见的页面内容,下半部分<script></script>标签中的代码为页面的JavaScript脚本代码。

具体结构展示如下(伪代码):

<!DOCTYPE html>
<html lang="en">
<head>
    ......
    <title>图像质量分析系统</title>
    ......
    <style type="text/css">
        /* 此处为页面中的CSS样式代码 */
    </style>
</head>
<body onload="initial_func()">
    <!-- 此处为可见的页面内容代码 -->
    <script type="text/javascript">
        // 此处为页面中的JavaScript脚本代码
    </script>
</body>
</html>

关于页面中展示的请求数据,可以通过后端处理并渲染到模板页面上;也可以通过前端的JavaScript脚本接收,再进行处理和渲染,最终展示在页面上。本例中使用的是前端进行数据接收和处理的方式。

接下来会重点介绍JavaScript代码中的get_assess_quality函数和handle_res函数。

注:前端页面中导入了jQuery库,下方的部分代码需要依赖jQuery库来实现。

(2)get_assess_quality函数介绍。

本实验中一个关键的js函数是get_assess_quality函数,函数代码展示如下:

function get_assess_quality(data) {
    // 定义一个函数,用于通过图片路径获取图像分析数据
    $('.identify_text').html("正在识别中...")
    $('.response_text').html("     数据获取中...")
    // 获取图像分析数据
    if (ajax_request != null) {
        // 关闭之前重复的ajax请求
        ajax_request.abort()
        $('.identify_text').html("正在识别中...")
        $('.response_text').html("     数据获取中...")
    }
    ajax_request = $.ajax({
        url: '/get_assess_quality',
        type: 'post',
        dataType: 'json',
        data: data,
    })
    .done(function(res) {
        handle_res(res)
    })
    .fail(function() {
        $('.identify_text').html("请求失败!")
        $('.response_text').html("")
    })
}

当用户点击左侧缩略图或是在右侧文本框输入URL地址并点击【检测】按钮时,便会调用此函数,将图片的URL地址信息发送给后端,并接收图片的质量评估数据(上传图片与此处的功能类似,但区别在于需要传递的数据为图片文件)。

此函数的核心功能是向后端发送一个Ajax请求,将网络图片的URL地址传递给后端名为/get_assess_quality的URL,并接收后端的处理结果。

如果成功返回图片的质量评估数据,数据的展示格式如下:

{
    "Response": {
        "LongImage": false,
        "BlackAndWhite": false,
        "SmallImage": false,
        "BigImage": true,
        "PureImage": false,
        "ClarityScore": 97,
        "AestheticScore": 98,
        "RequestId": "e84fdb9b-04a7-4d4f-a6cf-0f713d9e90c9"
    }
}

接下来将会通过handle_res函数对接收到的数据进行处理,并在页面上进行展示(下方会进行详细介绍)。

如果未能成功返回图片的质量评估数据,将会展示【请求失败!】的提示信息。

(3)handle_res函数介绍。

本实验中的另一个关键的js函数是handle_res函数,函数代码展示如下:

function handle_res(res) {
    // 处理接收到的数据
    const result_str = "清晰度:" + res.ClarityScore + "<br>" + "美观度:" + res.AestheticScore
    $('.identify_text').html(result_str)
    // 格式化字符串
    html_str = "AssessQuality:<br>" + JSON.stringify(res, null, 4).replace(/\n/g, '<br>').replace(/\s/g, '&nbsp');
    $('.response_text').html(html_str)
    $('.response_text').css("color: #fff; background-color: #1d212c")
}

此函数的功能是处理接收到的图片质量评估数据。拼接页面右侧的识别结果和Response中的展示文本,并最终将其展示在页面上。下图为函数handle_res处理并在页面中展示的数据示例:

4-3-1 handle_res处理并在页面中展示的数据

处理上面提到的两个函数,本项目中的JavaScript脚本还实现了部分前端页面的交互操作(如点击缩略图时的边框展示效果、点击上传本地图片标签的执行功能等),学员可通过浏览前端功能代码进一步学习理解。