使用H5的Canvas,实现证件照的识别

使用H5的Canvas,实现证件照的识别

需求:实现证件照上传时,提示用户证件照是否合法。
思路:在用户上传的照片上取三个像素点,判断像素点是否符合证件照的特点

项目中用到了element-plus中的el-upload 控件实现图片的上传,在实现此功能的过程中遇到了一系列的问题:
画布什么时候创建,创建的画布放在哪里…在画布里边拿不到原图的宽高等问题,经过多次尝试都已经解决。
首先创建一个画布(Canvas)

<canvas id="myCanvas"  style="opacity: 0;" v-if='1'></canvas> 

给存放证件照的img标签绑定id

  <el-upload
     class="avatar-uploader"
        ref='upload'
        action="https://jsonplaceholder.typicode.com/posts/"
        :show-file-list="false"
        :on-success="handleAvatarSuccess"
        :on-change="onChange"
        :before-upload="beforeAvatarUpload"
        :name='imgname'
        style="
            margin-top:19px;
            width: 109px;
            height: 136px;
            text-align: center;
            border: 2px dashed rgb(181, 181, 181);
            text-align:center;
            background-color:rgb(250, 250, 250)
        "
      >
        <img  :src="imageUrl" class="avatar" style="width:110px;height:136px;" id='scream'>                                             
 </el-upload>

这时候,我们需要考虑什么时候在把图片放到画布上比较好,
我这里是在,证件照上传之后,立即在画布上画出图片,在el-upload的onchange回调函数中进行,这样做思路没问题,但是onchange的调用时机(文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用),对此过程有影响,我们再添加文件时候已经调用了一次,这时候img里边还没有放东西,所以会报错。
解决这个问题:
我们可以使用一张图片来占用,我们提示用户的图标。(我这里一开始就给imageUrl绑定图片

继续刚才的思路:

    var c=document.getElementById("myCanvas");
              var ctx=c.getContext("2d");
              var img=document.getElementById('scream')
  img.onload = function() {           
                var imgW= img.offsetWidth
                var imgH= img.clientHeight
                ctx.drawImage(img,0,0,imgW,imgH,0,0,imgW,imgH);
}

使用context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); 剪切证件照,
各参数的含义:
img 规定要使用的图像、画布或视频。
sx 可选。开始剪切的 x 坐标位置。
sy 可选。开始剪切的 y 坐标位置。
swidth 可选。被剪切图像的宽度。
sheight 可选。被剪切图像的高度。
x 在画布上放置图像的 x 坐标位置。
y 在画布上放置图像的 y 坐标位置。
width 可选。要使用的图像的宽度(伸展或缩小图像)。
height 可选。要使用的图像的高度(伸展或缩小图像)。
(参考菜鸟教程)
这样处理看起来没问题,但是当我们接下来去取像素点的时候会发现,拿到的像素点并不是我们想要到,看一下img标签里边对图片的限制,显然,为了让图片在在页面上显示的更加美观,给用户一种良好的体验,我们需要对用户上传的大小不一的图片做一下限制,所以画布上画的并不是用户上传的图片。
为了拿到原图,解决思路:
可以在定义一个和el-upload绑定相同URL的img标,把它画到画布里:

 <img  :src="imageUrl" class="avatar" id='scream1' style="opacity: 0;" >  

接下来就只要拿到画布三个我们想要的像素点,就能解决问题了,
要求用户上传蓝底的证件照,我取的是左上角,右上角 和中间 三个点:

  ctx.drawImage(img,0,0,imgW,imgH,0,0,imgW,imgH);
   var rgb=ctx.getImageData(10,10,1,1).data;
  var rgb2=ctx.getImageData(imgW-10,10,1,1).data;
  var rgb3=ctx.getImageData(imgW/2+10,imgH/2-10,1,1).data;

接下来就是判断这三个点是否符合要求了,
我是去每个点的rgb进行判断的,像素点颜色的范围,需要你自己去找你想要的的范围
onchange 里边的关键代码:

  onChange(file,fileList){
//  判断图片内容
    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");
    var img=document.getElementById('scream1')
    var that=this
    img.onload = function() {           
      var imgW= img.offsetWidth
      var imgH= img.clientHeight
      ctx.drawImage(img,0,0,imgW,imgH,0,0,imgW,imgH);
      var rgb=ctx.getImageData(10,10,1,1).data;
      var rgb2=ctx.getImageData(imgW-10,10,1,1).data;
      var rgb3=ctx.getImageData(imgW/2+10,imgH/2-10,1,1).data;
      //左上角
      var rdata=rgb[0]
      var gdata=rgb[1]
      var bdata=rgb[2]
      // 右上角
      var rdata2=rgb2[0]
      var gdata2=rgb2[1]
      var bdata2=rgb2[2]
         //中间
      var rdata3=rgb3[0]
      var gdata3=rgb3[1]
      var bdata3=rgb3[2]         
       if( 0<=rdata && rdata<=79 &&
           0 <= gdata && gdata <=218
            &&240 <=bdata && bdata<=255
              && 0<=rdata2 && rdata2<=79 
              && 0<=gdata2 && gdata2<=218
              &&240<=bdata2 && bdata2<=255
              &&173<=rdata3 && rdata3<=244
               && 180<=gdata3 && gdata3<=215&&
               150<=bdata3 && bdata3<=187){
          // 图片内容合法
          this.abnrmal=0
         window.localStorage.setItem('abnrmal',this.abnrmal)
    }else{
      this.abnrmal=1
      // 图片内容不合法
      window.localStorage.setItem('abnrmal',this.abnrmal)
      that.$message.error('请上传蓝底的证件照')
    }
   }
   },

最后还有一个问题,就是千万不要有强迫症!!如果你一开始就把在画布组件上使用了,v-if / v-show 让图片不显示在页面上,那么就没办法进行了。
我们一开始随便在页面上操作,让这些东西消失在用户的视角,只需要最后,设置一下没用标签/组件的透明度(opacity)

<canvas id="myCanvas"  style="opacity: 0;" ></canvas>
 <img  :src="imageUrl" class="avatar" id='scream1' style="opacity: 0;" > 

效果截图
在这里插入图片描述

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值