vue 前端调用摄像头上传压缩图片后端保存调用微信OCR识别身份证

2023-11-01

前端

<template>
    <div style="padding-top: 5px;text-align: center" @click="imgClick()">
        <van-button color="#1EC7A6" :icon="require('../assets/icon/shoot.jpg')" type="info">拍照识别身份证</van-button>
        <input v-if="clearShow"  style="float: left;  display: none;" type="file" id='uploadFile'  accept="image/*"  @change="takePhoto($event)">

    </div>
</template>
    <script>

        export default {
            data() {
                return {
                   
                    info:{
                    },
                    clearShow:true
                }
            },
            methods: {
                takePhoto(e){//拍照功能---上传头像
                    this.clearShow = false;
                    var file=e.target.files[0]//获取文件对象
                    let self = this;
                    let Orientation;
                    let ndata;

                    if(file.size<=1* 1024* 1024){
                        //判断图片是否大于1M,是就直接上传
                        ndata=file;
                        self.postImg(ndata);
                    }else{
                        //反之压缩图片
                        let reader = new FileReader();
                        // 将图片2将转成 base64 格式
                        reader.readAsDataURL(file);
                        console.log(reader)
                        // 读取成功后的回调
                        reader.onloadend = function () {
                            let result = this.result;
                            let img = new Image();
                            img.src = result;
                            img.onload = function () {
                                let data = self.compress(img, Orientation);
                                self.headerImage = data;
                                ndata = self.compress(img, Orientation);

                                //BASE64转图片
                                var arr = ndata.split(','), mime = arr[0].match(/:(.*?);/)[1],
                                    bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
                                while (n--) {
                                    u8arr[n] = bstr.charCodeAt(n);
                                }
                                ndata = new File([u8arr], file.name, {type: mime})
                                self.postImg(ndata);
                            }
                        }
                    }
                                // this.uploadImg(file);

                },

                //删除图片

                //图片click
                imgClick:function(){
                    document.getElementById("uploadFile").click();
                },

                async postImg(blob) {
                    let filename = `${new Date().getTime()}.jpg`;
                    let file = new File([blob], filename, {type: 'image/jpg'});
                    let formData = new FormData();
                    formData.append('file', file);
                    formData.append('parentPath', "sign");//这个不是必须的,只是我自己设计的后台保存代码
                    let data = await this.$net.uploadImg({
                        url: this.$url.common.uploadImageToService,
                        data: formData
                    });
                    this.clearShow = true;
                    console.log(data)
                    console.log(data.data.data.url);
                    let getInfo= await this.$net.post({
                        url: this.$url.hosApi.getAccessToken,
                        data: {
                            img:data.data.data.url
                        }
                    });
                    console.log(getInfo);
                    if (getInfo.code==200){
                        this.info=getInfo.data;
                        
                    }else{
                        alert(getInfo.msg)
                    }



                },
                compress(img,Orientation) {
                    let canvas = document.createElement("canvas");
                    let ctx = canvas.getContext('2d');
                    //瓦片canvas
                    let tCanvas = document.createElement("canvas");
                    let tctx = tCanvas.getContext("2d");
                    let initSize = img.src.length;
                    let width = img.width;
                    let height = img.height;
                    //如果图片大于四百万像素,计算压缩比并将大小压至400万以下
                    let ratio;
                    if ((ratio = width * height / 4000000) > 1) {
                        console.log("大于400万像素")
                        ratio = Math.sqrt(ratio);
                        width /= ratio;
                        height /= ratio;
                    } else {
                        ratio = 1;
                    }
                    canvas.width = width;
                    canvas.height = height;
                    // 		铺底色
                    ctx.fillStyle = "#fff";
                    ctx.fillRect(0, 0, canvas.width, canvas.height);
                    //如果图片像素大于100万则使用瓦片绘制
                    let count;
                    if ((count = width * height / 1000000) > 1) {
                        console.log("超过100W像素");
                        count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
                        //            计算每块瓦片的宽和高
                        let nw = ~~(width / count);
                        let nh = ~~(height / count);
                        tCanvas.width = nw;
                        tCanvas.height = nh;
                        for (let i = 0; i < count; i++) {
                            for (let j = 0; j < count; j++) {
                                tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
                                ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
                            }
                        }
                    } else {
                        ctx.drawImage(img, 0, 0, width, height);
                    }
                    //修复ios上传图片的时候 被旋转的问题
                    if(Orientation != "" && Orientation != 1){
                        switch(Orientation){
                            case 6://需要顺时针(向左)90度旋转
                                this.rotateImg(img,'left',canvas);
                                break;
                            case 8://需要逆时针(向右)90度旋转
                                this.rotateImg(img,'right',canvas);
                                break;
                            case 3://需要180度旋转
                                this.rotateImg(img,'right',canvas);//转两次
                                this.rotateImg(img,'right',canvas);
                                break;
                        }
                    }
                    //进行最小压缩
                    let ndata = canvas.toDataURL('image/jpeg', 0.1);

                    console.log('压缩前:' + initSize);
                    console.log('压缩后:' + ndata.length);
                    console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");
                    tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;


                    return ndata;
                }

            }
        }
    </script>

后端

上传图片

 @PostMapping("uploadImg")
    public Result uploadContentImg(@RequestParam("parentPath") String parentPath, @RequestParam("file") MultipartFile file) throws IOException {
        String fileName = file.getOriginalFilename();
        fileName = fileName.substring(fileName.lastIndexOf("."));//截取后缀
        fileName = System.currentTimeMillis()+ MyUtil.getRandomString(6)+fileName;//添加后缀
        String serviceLocalPath =getRealPath(parentPath,fileName);
        File realFile = new File(serviceLocalPath);
        realFile.getParentFile().mkdirs();
        //4.把浏览器上传的文件保存到本地
        file.transferTo(realFile);
        String path = parentPath+"/"+fileName;
       
        String host =  getImgHomeUrl(httpRequest);
        UploadImage bean = new UploadImage();
        bean.setPath(serviceLocalPath);
        bean.setHost(host);
        bean.setUrl(host+path);
        return ResultGenerator.genSuccessMessage(bean);
    }
    //获取网站图片地址
      public static String getImgHomeUrl(HttpServletRequest req) {
        String basePath = null;
        if(getHostPath()!=null){
            basePath = getHostPath() + req.getContextPath();
        }else{
            basePath = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() +  req.getContextPath();
        }
        return basePath + getStaticAccessPath();
    }
     public static String getRealPath(String parentFileName,String filename) {
        return getUploadFolder()+ File.separator+ parentFileName +File.separator+filename;
    }

调用微信ocr

   @RequestMapping(value = "/getAccessToken", method = RequestMethod.POST)
    public Result getAccessToken(@RequestBody Map map) {
//获取本地缓存accessToken
        String accessToken = WeChatCache.ACCESS_TOKEN.get(hosUserService.getHosUserByToken(SysContent.getHeader().getToken()).getCurrentPlatId().toString());

        String url="https://api.weixin.qq.com/cv/ocr/idcard?img_url="+map.get("img")+"&access_token="+accessToken;
        JSONObject forObject = restTemplate.getForObject(url, JSONObject.class);
        if (!StringUtils.isEmpty(forObject.getString("errcode")) && "0".equals(forObject.getString("errcode"))) {
            return ResultGenerator.genSuccessMessage(forObject);
        }else {
            throw new YXException(forObject.getString("errmsg"));
        }


    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue 前端调用摄像头上传压缩图片后端保存调用微信OCR识别身份证 的相关文章

随机推荐

  • 解决Flutter旋转屏幕状态栏空缺的问题

    问题 最近要实现一个视频播放器 全屏播放时需要旋转屏幕 把案例拿出来试了一下 旋转屏幕后呈现的状态是这样 解决办法 打开项目下android app src main res values styles xml 添加
  • 对象相等判断&&值传递

    文章目录 对象相等判断 和 equals 的区别是什么 hashCode 与 equals 重要 对象的相等与指向他们的引用相等 两者有什么不同 值传递 对象相等判断 和 equals 的区别是什么 它的作用是判断两个对象的地址是不是相等
  • STP协议详解

    STP协议详解 文章目录 STP协议详解 前言 一 STP协议的运行原理 二 STP协议中ROOT RP DP的选举规则 三 端口状态disable listening learning forwarding blocking所代表的含义
  • vue3组合式api 父子组件数据同步v-model语法糖的用法

    V model 大多数情况是用在 表单数据上的 但它不止这一个作用 父子组件的数据同步 有一个 语法糖 v model 这个方法简化了语法 在elementplus中 都有很多地方使用 所以我们要理解清楚 父组件 使用 v model 向子
  • 【牛客SQL】SQL10 获取所有非manager的员工emp_no

    题目描述 描述 有一个员工表employees简况如下 有一个部门领导表dept manager简况如下 请你找出所有非部门领导的员工emp no 以上例子输出 示例1 输入 drop table if exists dept manage
  • 前端学习——jQuery基础

    一 引入jQuery的js文件 此处是下载好的jquery的js文件 也可以引入cdn 二 jQuery的入口函数 三 DOM对象和jQuery对象 div div 建一个盒子
  • react——state(状态机)

    h1 h1 h1 react state 状态 h1 p react把组件看成是一个状态机 state machines 通过与用户的交互 实现不同状态渲染UI 让用户界面和数据保持一致 p p react里 只需要更新组件的state 然
  • 【Qt教程】1.7 - Qt5带参数的信号、信号重载、带参数的槽函数、槽函数重载

    原理 与C 语法一致 信号 槽函数都可以发生重载 使其在名称不变的情况下 传递过程可以携带参数 示例说明 我们从一个最普通的信号槽工程中 来修改 对信号 槽进行重载 使信号 槽携带参数 1 普通信号 工程源码 widget h ifndef
  • rank、dense_rank、row_number函数的区别

    这四个 RANK DENSE RANK NTILE ROW NUMBER 函数 都是用来对数据库中的数据进行排名的 在他们的功能各有千秋 下面介绍一下这四个函数的功能和用法 首先创建一个Student表 CREATETABLEStudent
  • 树莓派安装opencv教程

    我使用的镜像版本为 Linux version 5 10 103 v7l dom buildbot arm linux gnueabihf gcc 8 Ubuntu Linaro 8 4 0 3ubuntu1 8 4 0 使用Python3
  • C++ 仿函数的分类

    一 概述 仿函数 functor 就是使一个类的使用看上去象一个函数 其实现就是类中实现一个operator 这个类就有了类似函数的行为 就是一个仿函数类了 有些功能的的代码 会在不同的成员函数中用到 想复用这些代码 1 公共的函数 可以
  • 普通人如何抓住AI这个风口

    随着科技的发展 人工智能 AI 已经成为当今社会的风口浪尖 越来越多的行业正在应用AI技术 新的职业和商业机会也随之出现 那么 作为普通人 我们应该如何抓住这个风口呢 来看看 AI硅基小助手 是如何解答的 1 学习AI相关技能 学习AI相关
  • Shiro和Spring Security的简单对比

    Shiro和Spring Security是Java中常用的两种安全认证框架 安全认证主要包括认证和授权鉴权两部分 认证指应用程序验证一个用户信息的过程 应用程序需要确认当前的用户是否是合法的用户 用户会向应用程序提供两部分数据 身份信息和
  • Java学习-冒泡排序

    冒泡排序 通俗的理解就是将一列无序的数字按照从大到小或者从小到大的顺序进行排序的一种简单的算法 在Java中一般是将数组使用冒泡排序的方法进行排序 大致原理是遍历数组元素 然后每两个之间进行比较 将较大值或者较小值按照自己想要的排序结果进行
  • YOLOV7调用本地USB摄像头和自己训练的权重文件实时检测目标

    作者新手 挣扎于毕业的菜鸡一枚 有问题欢迎讨论 最近在做课题时想直接调用本地摄像头来测试一下自己的训练结果 查到的文章多用到onnx openvino等格式转换部署 但作者没有这方面需求 折腾一会失败了 后来发现yolo系列自带了此功能 只
  • Linux xarges

    对于管道 之后的一部分命令可以用stdin进行输入 如 cat a grep test 但有些命令只能用参数形式 就要使用xargs了 xargs可以将stdin转化为参数 类似于find命令中的 exec选项 xargs也可以将单行或多行
  • 电赛经验分享

    2019 TI杯过程和经验分享 在这里我也是第一次写博客 看博客已经有一年多了吧 为什么要在这一次写博客呢 一是因为这一次比赛对我的影响很深 也算试一次经历和教训吧 二是因为最后一次参加TI杯大赛 在 比赛之前我们是做了充分的准备 把前两年
  • 如何用计算机名添加的打印机,如何添加打印机(如何在电脑上安装打印机)

    如何添加打印机 如何在电脑上安装打印机 平时在生活中 我们要将电子档的文件打印出来 都需要使用到打印机 传统的打印机都是以电脑为主 今天就教大家如何在电脑上安装打印机 电脑上安装打印机的详细步骤 1 双击打开桌面上的 控制面板 如果桌面上没
  • cadence布局布线常见问题详解

    cadence布局布线常见问题详解 1 怎样建立自己的元件库 建立了一个新的project后 画原理图的第一步就是先建立自己所需要的库 所采用的工具就是part developer 首先在建立一个存放元件库的目录 如mylib 然后用写字板
  • vue 前端调用摄像头上传压缩图片后端保存调用微信OCR识别身份证

    前端