canvas初体验-图片上画方框

开发环境:ionic + typeScript

需求:手机拍车牌号照片传至后端,后端返回对应车辆信息以及车牌号在图片位置,前端用方框框出来。

先看一下后端返回格式:

[{
  rect: [11, 22, 33, 44], // x1, y1, x2, y2
  p: 0.876543, // 车牌准确率
  license: '鲁A12345' // 识别内容
}]
  1. html部分
<div class="canvasStyle">
  <canvas id="myCanvas" height="300" height="300"></canvas>
</div>
  1. css部分
.canvasStyle {
  text-align: center;
  #myCanvas {
    width: 100%;
  }
}
  1. ts部分
/**
* @params
* array 后端返回数据
* base64Img 图片代码
*/
success (array, base64Img) {
  if (!array.length) {
    this.util.toast('未识别到车牌', 'warning')
    return
  }
  // 绘制出图片与方框
  let canvas = document.getElementById('myCanvas') as HTMLCanvasElement
  // 设置canvas宽高
  canvas.width = document.body.clientWidth
  canvas.height = document.body.clientHeight
  let ctx: CanvasRenderingContext2D = canvas.getContext('2d'),
    img = new Image(),
    imgW = 0,
    imgH = 0,
    rectArray = []
  img.src = base64Img
  img.onload = function() {
    imgW = img.width
    imgH = img.height
    // 图片超过屏幕宽度则满屏 否则自适应
    if ((imgH * canvas.width / imgW) > canvas.height) {
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
    } else {
      ctx.drawImage(img, 0, 0, canvas.width, imgH * canvas.width / imgW)
    }
    // 有识别结果 画框
    if (array.length) {
      // 计算展示图与原图缩小比例
      let per = parseFloat((canvas.offsetWidth / imgW).toFixed(2))
      array.forEach((element, index) => {
        ctx.strokeStyle = '#ff0000' // 框颜色
        ctx.lineWidth = 2 // 框宽度
        let [x1, y1, x2, y2] = element.rect
        // 开始画框
        ctx.strokeRect(x1 * per, y1 * per, (x2 - x1) * per, (y2 - y1) * per)
        
        // 记录下几个框的信息 点击时要用
        rectArray.push({ x: x1 * per, y: y1 * per, width: (x2 - x1) * per, height: (y2 - y1) * per, plateNum: element.license })
      })
      // 画布点击事件
      canvas.addEventListener('click', function(e) {
        let p = getEventPosition(e)
        draw(p)
      }, false)
    }
    let _this = this
    function getEventPosition(ev) {
      if (ev.layerX || ev.layerX === 0) {
        return { x: ev.layerX, y: ev.layerY }
      } else if (ev.offsetX || ev.offsetX === 0) { // Opera
        return { x: ev.offsetX, y: ev.offsetY }
      }
    }
    function draw(p) {
      rectArray.forEach(function(v) {
        ctx.beginPath()
        ctx.rect(v.x, v.y, v.width, v.height)
        // 点击不同车牌重新获取数据
        if(p && ctx.isPointInPath(p.x, p.y)) {
          _this.openMode(v.plateNum)
        }
      })
    }
  }, 500)
}

第一次尝试canvas, 代码潦草,多多包涵。

— END —

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值