1、安装依赖

// 安装Element-UI
npm install element-ui --save
// 安装 ocr 和 ocrdet
npm i @paddlejs-models/ocrdet@0.0.3 --save
npm i @paddlejs-models/ocr@1.1.2 --save

2、完整代码

<!--
 * @Descripttion: 图片识别
 * @version: 0.0.1
 * @Author: PengShuai
 * @Date: 2023-12-21 10:03:47
 * @LastEditors: PengShuai
 * @LastEditTime: 2023-12-22 09:41:50
-->
<template>
  <div class="imageRecognition">
    <div class="upFile">
      <el-upload
        class="upload-demo"
        action="abc"
        :auto-upload="false"
        :on-change="onHandleChange"
        :show-file-list="false"
      >
        <el-button size="medium" type="primary"
          >上传图片<i class="el-icon-upload el-icon--right"></i
        ></el-button>
      </el-upload>
    </div>
    <div class="box">
      <div class="left">
        <img :src="image" ref="image" />
      </div>
      <div class="center">
        <canvas ref="canvas"></canvas>
      </div>
      <div class="right">
        <div ref="text" class="text" :style="textStyle">
          <p v-for="(text, index) in texts" :key="index">{{ text }}</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import * as ocr from '@paddlejs-models/ocr'
import { drawBox } from '@/utils/ocrUtils'
export default {
  name: 'imageRecognition',
  data() {
    return {
      image: '',
      texts: [],
      textStyle: {
        width: '',
        height: '',
      },
    }
  },
  mounted() {
    this.initPage()
  },
  methods: {
    /**
     *@Descripttion:页面初始化
     *@Author: PengShuai
     *@Date: 2023-12-21 10:49:26
     */
    async initPage() {
      const loading = this.$loading({
        lock: true,
        text: '模型加载中......',
        spinner: 'el-icon-loading',
        background: 'rgba(255, 255, 255, 0.95)',
      })
      try {
        // 模型初始化
        await ocr.init()
        this.$message({
          message: '加载成功',
          type: 'success',
        })
        loading.close()
      } catch (err) {
        this.$message({
          message: '加载失败,请刷新页面',
          type: 'error',
        })
        loading.close()
      }
    },
    /**
     *@Descripttion:上传事件
     *@Author: PengShuai
     *@Date: 2023-12-21 10:49:36
     */
    onHandleChange(file) {
      this.image = URL.createObjectURL(file.raw)

      setTimeout(() => {
        this.getRecognize()
      }, 600)
    },

    async getRecognize() {
      const image = this.$refs.image
      const canvas = this.$refs.canvas
      const res = await ocr.recognize(image)
      const { text, points } = res
      drawBox(points, image, canvas)
      this.textStyle.width = image.width - 40 + 'px'
      this.texts = text
    },
  },
}
</script>

<style lang="less" scoped>
.imageRecognition {
  .box {
    display: flex;
    div {
      flex: 1;
    }
  }
}
</style>

3、{ drawBox } utils文件夹下创建 ocrUtils.js

// utils文件夹下创建 ocrUtils.js
export function drawBox(points, imgElement, canvasOutput) {
  canvasOutput.width = imgElement.width
  canvasOutput.height = imgElement.height
  const ratio = imgElement.naturalHeight / imgElement.height

  const ctx = canvasOutput.getContext('2d')
  ctx.drawImage(imgElement, 0, 0, canvasOutput.width, canvasOutput.height)
  points.forEach((point) => {
    // 开始一个新的绘制路径
    ctx.beginPath()
    // 设置线条颜色为红色
    ctx.strokeStyle = 'red'
    // 设置路径起点坐标
    ctx.moveTo(point[0][0] / ratio, point[0][1] / ratio)
    ctx.lineTo(point[1][0] / ratio, point[1][1] / ratio)
    ctx.lineTo(point[2][0] / ratio, point[2][1] / ratio)
    ctx.lineTo(point[3][0] / ratio, point[3][1] / ratio)
    ctx.closePath()
    ctx.stroke()
  })
}

export function drawText(text, points, imgElement, canvasOutput) {
  canvasOutput.width = imgElement.width
  canvasOutput.height = imgElement.height
  const ratio = imgElement.naturalHeight / imgElement.height

  const ctx = canvasOutput.getContext('2d')
  points.forEach((point, index) => {
    // 开始一个新的绘制路径
    ctx.beginPath()
    // 设置线条颜色为红色
    ctx.strokeStyle = 'red'
    // 设置路径起点坐标
    ctx.moveTo(point[0][0] / ratio, point[0][1] / ratio)
    ctx.lineTo(point[1][0] / ratio, point[1][1] / ratio)
    ctx.lineTo(point[2][0] / ratio, point[2][1] / ratio)
    ctx.lineTo(point[3][0] / ratio, point[3][1] / ratio)
    ctx.closePath()
    ctx.stroke()

    ctx.font = '30px 黑体'
    ctx.fillText(
      text[index],
      point[3][0] / ratio,
      point[3][1] / ratio,
      point[1][0] / ratio - point[0][0] / ratio
    )
  })
}


4、示例

posted on 2023-12-22 09:54  丶凉雨拾忆  阅读(392)  评论(0编辑  收藏  举报