国庆节一直在下雨,我也没有办法出去愉快的玩耍,突然想到之前有在服务器上部署一个ocr文字识别接口,于是就想要做一个在线OCR识别工具,说干就干,但是打开了vs code却无从下手,页面应该怎么做呢?

想直接用识别接口的:https://zn.gg/tools/ocr

思路

  1. 首先需要上传图片
  2. 然后把图片转换成base64编码
  3. 之后通过ajax请求接口
  4. 展示返回识别到的内容

上传图片并获得base64编码

上传图片的话使用表单的input标签就可以,然后使用FileReader可以读取到图片内容,那么代码如下:

<input type="file" accept="image/jpeg,image/png,image/jpg,image/png" onchange="uploadImg(this)" multiple/>
    <script>
        function uploadImg(file) {
            if (file && file.files[0]) {
                var reader = new FileReader();
                reader.onload = function(evt) {
                    var imageData = (evt.target.result.replace(/.*?base64,/, ""))
                }
                return reader.readAsDataURL(file.files[0])
            }
        }
    </script>

imageData就是图片的base64编码,我使用正则表达式 /.?base64,/* 去掉了前缀,拿到了图片真正的base64编码。

ajax获取识别结果

那么之后就需要网络请求了,我使用ajax进行网络请求,所以首先需要导入jquery库,然后带入image参数进行请求,接口地址是:https://zn.gg/api/common/v1/ocr ,另外这个识别是需要一个过程的,所以设置了一下超时时间为60秒,为了方便解析返回的结果,所以设置了dataType为json,这样就可以直接获取结果了。在得到结果之后我们需要解析一下结果,这里使用eval来把字符串转换成了数组,通过循环遍历出结果,存放在变量msg中。

$.ajax({
    type: 'POST',
    url: 'https://zn.gg/api/common/v1/ocr',
    timeout: '60000',
    dataType: 'json',
    data: {
        image: imageData
    },
    success: function(data) {

        let arr = eval('(' + data.value[0] + ')')
        var msg = ""
        arr.forEach(element => {
            msg += element
        });
       
       //msg就是识别结果。
        
    },
    error: function(data) {
        
    }
})

核心页面的设置

核心地方为使用了一个大的div里面包含两个小的div,设置大div的宽高,然后使用margin的auto让其居中,两个小的div设置为浮动,这样就可以左右各有一个div了。这两个div分别为source和result,source有input标签,用于上传图片,还有img标签用于展示;result里面有一个textarea文本域用来显示识别结果。这个代码由于涉及到style和html所以就不展示了,可以直接看最下面的完整代码。

美化

这个还是比较好玩的,一共有两个部分:

  1. 上传按钮
  2. 识别过程中的图片扫描效果

上传按钮美化

首先来说这个这个上传按钮,一个input标签,类型为file,我刚开始使用css增加背景颜色等试图让它变得好看一些,可是根本没有效果。于是换了一种思路:使用绝对位置,让input覆盖在另外一个元素上面,让input的宽高和被覆盖的元素相同,设置input透明,这样只需要没话被覆盖的元素就可以了。代码如下:

.core .source .button-upload {
    position: relative;
}

.core .source .button-upload .button-upload-show {
    position: absolute;
    width: 120px;
    height: 45px;
    background: cornflowerblue;
}

.core .source .button-upload .button-upload-show p {
    line-height: 45px;
    text-align: center;
    color: white;
}

.core .source .button-upload #button-upload-hidden {
    position: absolute;
    opacity: 0;
    width: 120px;
    height: 45px;
}
<div class="core">
    <div class="source">
        <div class="button-upload">
            <div class="button-upload-show">
                <p>上传图片</p>
            </div>
            <input id="button-upload-hidden" type="file" accept="image/png,image/jpg,image/jpeg" onchange="uploadImg(this)">
        </div>
    </div>
</div>

上传图片





图片扫描效果

这个看起来很炫酷,实际上就是一个很简单的动画,放一个div覆盖在图片上,然后使用动画设置div的高度和透明度,这个div的背景是一个渐变色的蓝色背景,这样就实现了上下扫描的效果。上传图片后设置展示效果的div的display为block,接收到返回后设置为none,这样就实现了扫描效果。

完整代码

<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>OCR 文字识别</title>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

</head>

<style>
    @keyframes scan {
        0% {
            height: 0;
        }
        to {
            opacity: 0;
            height: 298px;
        }
    }
    
    * {
        margin: 0;
        padding: 0;
    }
    
    header {
        height: 180px;
        width: 100vw;
        background: #f1f1f1;
    }
    
    header p {
        text-align: center;
        line-height: 180px;
        font-size: 40px;
    }
    
    .core {
        height: 540px;
        width: 1000px;
        margin: 20px auto;
    }
    
    .core .source {
        float: left;
        width: 480px;
        margin: 0 10px;
    }
    
    .core .source .imageScan {
        display: none;
        position: absolute;
        width: 480px;
        height: 298px;
        animation: scan 1.2s infinite;
        background: linear-gradient(180deg, transparent, rgb(60, 166, 228));
    }
    
    .core .source #imgPreview {
        width: 480px;
        height: 298px;
    }
    
    .core .source .button-upload {
        position: relative;
    }
    
    .core .source .button-upload .button-upload-show {
        position: absolute;
        width: 120px;
        height: 45px;
        background: cornflowerblue;
    }
    
    .core .source .button-upload .button-upload-show p {
        line-height: 45px;
        text-align: center;
        color: white;
    }
    
    .core .source .button-upload #button-upload-hidden {
        position: absolute;
        opacity: 0;
        width: 120px;
        height: 45px;
    }
    
    .core .result {
        float: left;
        width: 480px;
        margin: 0 10px;
    }
    
    .core .result #resultMsg {
        width: 480px;
        height: 298px;
    }
</style>

<body>
    <header>
        <p>OCR 文字识别</p>
    </header>
    <div class="core">
        <div class="source">
            <div id="imageScan" class="imageScan"></div>
            <img id="imgPreview" src="" alt="">
            <div class="button-upload">
                <div class="button-upload-show">
                    <p>上传图片</p>
                </div>
                <input id="button-upload-hidden" type="file" accept="image/png,image/jpg,image/jpeg" onchange="uploadImg(this)">
            </div>
        </div>
        <div class="result">
            <textarea name="" id="resultMsg" cols="30" rows="10"></textarea>
        </div>
    </div>
    <script>
        let imageScan = document.getElementById("imageScan")

        let imgPreview = document.getElementById("imgPreview")
        let resultMsg = document.getElementById("resultMsg")


        function uploadImg(file) {
            if (file && file.files[0]) {
                imageScan.style.display = "block"
                let reader = new FileReader()
                reader.onload = function(evt) {
                    imgPreview.src = evt.target.result
                    let imageData = evt.target.result.replace(/.*?base64,/, "")
                    $.ajax({
                        type: 'POST',
                        url: 'https://zn.gg/api/common/v1/ocr',
                        timeout: '60000',
                        dataType: 'json',
                        data: {
                            image: imageData
                        },
                        success: function(data) {

                            let arr = eval('(' + data.value[0] + ')')
                            var msg = ""
                            arr.forEach(element => {
                                msg += element
                            });
                            resultMsg.innerText = msg
                            imageScan.style.display = "none"
                        },
                        error: function(data) {
                            imageScan.style.display = "none"
                        }
                    })

                }
                return reader.readAsDataURL(file.files[0])
            }
        }
    </script>
</body>

</html>

您可能感兴趣的: