最近项目中有一个需求,ocr识别银行卡号及卡类型。一般来说这种需求都是后端识别出来之后接口返回给前端。但我想试试纯前端怎么去实现,所以:

       <!-- 卡号输入框 -->
        <van-field
          v-model="formattedCardNumber"
          placeholder="请输入卡号"
          type="tel"
          clearable
        >
          <template #label>
            <span class="custom-label">
              卡号
              <img
                class="info-icon"
                src="@/assets/zjwallet/bindCard/info.svg"
                alt="Info"
              />
            </span>
          </template>
          <template #button>
            <van-icon name="scan" @click="scanCardNumber" />
          </template>
        </van-field>


    <!-- 文件输入 -->
      <input
        type="file"
        ref="fileInput"
        accept="image/*"
        @change="handleFileUpload"
        style="display: none"
      />
     
// 先装一个插件  
npm install tesseract.js@4.1.1(这个版本可能更稳定一些)

import Tesseract from "tesseract.js";


  data() {
    return {
      cardNumber: "",
     
      bankName: "",
     
      bankList: [
        { name: "中国招商银行", prefix: "621483" },
        { name: "中国工商银行", prefix: "621225" },
        { name: "中国建设银行", prefix: "621700" },
        // Add more banks and their prefixes as needed
      ],
    };
  }
// methods里面写这些方法
   
scanCardNumber() {
      // 触发文件输入以选择图像
      this.$refs.fileInput.click();
    },


    handleFileUpload(event) {
      const file = event.target.files[0];
      if (file) {
        Tesseract.recognize(file, "chi_sim", {
          logger: (m) => console.log(m),
        }).then(({ data: { text } }) => {
          // 从OCR文本中提取卡号
          const cardNumberMatch = this.reliableExtract(text);
          if (cardNumberMatch) {
            this.cardNumber = cardNumberMatch;
            this.determineBankName(cardNumberMatch);
          } else {
            alert("Could not find a valid card number in the image.");
          }
        });
      }
    },


    reliableExtract(text) {
      // 按行分割后,找到包含"621225"的行
      const lines = text.split("\n");
      const cardLine = lines.find((line) => line.includes("62"));
      if (cardLine) {
        // 提取该行所有数字并合并
        return cardLine.replace(/\D/g, "");
      }
      return null;
    },

    determineBankName(cardNumber) {
      for (const bank of this.bankList) {
        if (cardNumber.startsWith(bank.prefix)) {
          this.bankName = bank.name;
          return;
        }
      }
      this.bankName = "未知银行";
    },

这样基本就实现了比较简单的。也算是一个小demo吧。如果想要识别出 借记卡或者信用卡  或者更全面的银行信息,那你可能需要去维护一个银行卡BIN号的数据库(也可以mock数据自己玩一玩),然后再根据自己公司需求情况去调试 整理一下符合业务逻辑的代码。当然 只要是项目经理不傻,这种东西应该不会让前端去做。如果真有需要,可以参考一下。也可以通过第三放API去实现

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐