跳到主要内容

卡证识别

从5.1.1(19)开始,CardRecognition接口中的callback参数废弃,请使用onResult代替。

场景介绍

卡证识别控件提供身份证(目前仅支持中国大陆二代身份证,且不包含民汉双文身份证)、行驶证、驾驶证、护照、银行卡的结构化识别服务,满足卡证的自动分类功能,系统可自动判断所属卡证类型并返回结构化信息和卡证图片信息。

对于需要填充卡证信息的场景,如身份证、银行卡信息等,可使用卡证识别控件读取OCR(Optical Character Recognition)信息,将结果信息返回后进行填充。支持单独识别正面、反面,或同时进行双面识别。

图1 银行卡识别示意图

约束与限制

  • 支持的语种类型:简体中文、英文。
  • 卡证识别暂时只支持中国二代身份证、中国国内银行卡、中国护照、中国驾驶证、中国行驶证(暂不支持中国港澳台地区及海外证件)。
  • 卡证需要保持与真实证件一致的长宽比、没有形变、正向拍摄角度小于30度。
  • 卡证图像清晰、完整。无摩尔纹、无遮挡、无反光、无卡套。
  • 不允许被其他组件或窗口遮挡。

接口说明

以下仅列出demo中调用的部分主要接口,具体API说明详见API参考

接口名描述
CardRecognition卡证识别控件
CardRecognitionResult卡证识别结果

开发步骤

  1. 将卡证识别控件相关的类添加至工程。

    import { CardRecognition, CardRecognitionResult, CardType, CardSide, CardRecognitionConfig, ShootingMode, CardContentConfig, BankCardConfig } from "@kit.VisionKit";
  2. 配置页面的布局,选择需要识别的卡证类型和需要识别的卡证页面,配置对应设置项,在回调中获取结果返回值。

    以下分别为身份证、银行卡、护照、驾驶证和行驶证的示例代码。

    import { hilog } from '@kit.PerformanceAnalysisKit';

    const TAG = 'CardRecognition'

    @Entry
    @Component
    struct Index {
    build() {
    Column() {
    // 身份证
    CardRecognition({
    supportType: CardType.CARD_ID,
    // 身份证可双面识别
    cardSide: CardSide.DEFAULT,
    cardRecognitionConfig: {
    defaultShootingMode: ShootingMode.MANUAL,
    isPhotoSelectionSupported: true
    },
    onResult: ((params: CardRecognitionResult) => {
    hilog.info(0x0001, TAG, `params code: ${params.code}`)
    hilog.info(0x0001, TAG, `params cardType: ${params.cardType}`)
    hilog.info(0x0001, TAG, `params cardInfo front: ${JSON.stringify(params.cardInfo?.front)}`)
    hilog.info(0x0001, TAG, `params cardInfo back: ${JSON.stringify(params.cardInfo?.back)}`)
    })
    })
    }
    .height('100%')
    .width('100%')
    }
    }
    import { hilog } from '@kit.PerformanceAnalysisKit';

    const TAG = 'CardRecognition'

    @Entry
    @Component
    struct Index {
    build() {
    Column() {
    // 银行卡
    CardRecognition({
    supportType: CardType.CARD_BANK,
    // 银行卡为单面识别
    cardSide: CardSide.FRONT,
    cardRecognitionConfig: {
    defaultShootingMode: ShootingMode.MANUAL,
    isPhotoSelectionSupported: true,
    cardContentConfig: { bankCard: { isBankNumberDialogShown: true} }
    },
    onResult: ((params: CardRecognitionResult) => {
    hilog.info(0x0001, TAG, `params code: ${params.code}`)
    hilog.info(0x0001, TAG, `params cardType: ${params.cardType}`)
    hilog.info(0x0001, TAG, `params cardInfo: ${JSON.stringify(params.cardInfo?.main)}`)
    })})
    }
    .height('100%')
    .width('100%')
    }
    }
    import { hilog } from '@kit.PerformanceAnalysisKit';

    const TAG = 'CardRecognition'

    @Entry
    @Component
    struct Index {
    build() {
    Column() {
    // 护照
    CardRecognition({
    supportType: CardType.CARD_PASSPORT,
    // 护照为单面识别
    cardSide: CardSide.FRONT,
    cardRecognitionConfig: {
    defaultShootingMode: ShootingMode.MANUAL,
    isPhotoSelectionSupported: true
    },
    onResult: ((params: CardRecognitionResult) => {
    hilog.info(0x0001, TAG, `params code: ${params.code}`)
    hilog.info(0x0001, TAG, `params cardType: ${params.cardType}`)
    hilog.info(0x0001, TAG, `params cardInfo: ${JSON.stringify(params.cardInfo?.main)}`)
    })})
    }
    .height('100%')
    .width('100%')
    }
    }
    import { hilog } from '@kit.PerformanceAnalysisKit';

    const TAG = 'CardRecognition'

    @Entry
    @Component
    struct Index {
    build() {
    Column() {
    // 驾驶证
    CardRecognition({
    supportType: CardType.CARD_DRIVER_LICENSE,
    // 驾驶证可双面识别
    cardSide: CardSide.DEFAULT,
    cardRecognitionConfig: {
    defaultShootingMode: ShootingMode.MANUAL,
    isPhotoSelectionSupported: true
    },
    onResult: ((params: CardRecognitionResult) => {
    hilog.info(0x0001, TAG, `params code: ${params.code}`)
    hilog.info(0x0001, TAG, `params cardType: ${params.cardType}`)
    hilog.info(0x0001, TAG, `params cardInfo front: ${JSON.stringify(params.cardInfo?.front)}`)
    hilog.info(0x0001, TAG, `params cardInfo back: ${JSON.stringify(params.cardInfo?.back)}`)
    })
    })
    }
    .height('100%')
    .width('100%')
    }
    }
    import { hilog } from '@kit.PerformanceAnalysisKit';

    const TAG = 'CardRecognition'

    @Entry
    @Component
    struct Index {
    build() {
    Column() {
    // 行驶证
    CardRecognition({
    supportType: CardType.CARD_VEHICLE_LICENSE,
    // 行驶证可双面识别
    cardSide: CardSide.DEFAULT,
    cardRecognitionConfig: {
    defaultShootingMode: ShootingMode.MANUAL,
    isPhotoSelectionSupported: true
    },
    onResult: ((params: CardRecognitionResult) => {
    hilog.info(0x0001, TAG, `params code: ${params.code}`)
    hilog.info(0x0001, TAG, `params cardType: ${params.cardType}`)
    hilog.info(0x0001, TAG, `params cardInfo front: ${JSON.stringify(params.cardInfo?.front)}`)
    hilog.info(0x0001, TAG, `params cardInfo back: ${JSON.stringify(params.cardInfo?.back)}`)
    })
    })
    }
    .height('100%')
    .width('100%')
    }
    }

开发实例

Index.ets

// 卡证识别开发实例分两页实现,一页为卡证识别入口页,一页为卡证识别实现页
// 卡证识别入口页,需引入卡证识别实现页,以下文实例为例,实现页文件名为CardDemoPage
import { CardDemoPage } from './CardDemoPage'

@Entry
@Component
struct MainPage {
@Provide('pathStack') pathStack: NavPathStack = new NavPathStack()

@Builder
PageMap(name: string) {
if (name === 'cardRecognition') {
CardDemoPage()
}
}

// 卡证识别入口按钮
build() {
Navigation(this.pathStack) {
Button('CardRecognition', { stateEffect: true, type: ButtonType.Capsule })
.width('50%')
.height(40)
.onClick(() => {
this.pathStack.pushPath({ name: 'cardRecognition' })
})
}.title('卡证识别控件demo').navDestination(this.PageMap)
.mode(NavigationMode.Stack)
}
}

CardDemoPage.ets

// 卡证识别实现页,文件名为CardDemoPage,需被引入至入口页
import { CardRecognition, CardRecognitionResult, CardType, CardSide, ShootingMode } from "@kit.VisionKit"
import { hilog } from '@kit.PerformanceAnalysisKit';

const TAG: string = 'CardRecognitionPage'

// 卡证识别页,用于加载UIExtensionAbility
@Component
export struct CardDemoPage {
@State cardDataSource: Record<string, string>[] = []
@Consume('pathStack') pathStack: NavPathStack

build() {
NavDestination() {
Stack({ alignContent: Alignment.Top }) {
Stack() {
this.cardDataShowBuilder()
}
.width('80%')
.height('80%')

CardRecognition({
// 此处选择身份证类型作为示例
supportType: CardType.CARD_ID,
cardSide: CardSide.DEFAULT,
cardRecognitionConfig: {
defaultShootingMode: ShootingMode.MANUAL,
isPhotoSelectionSupported: true
},
onResult: ((params: CardRecognitionResult) => {
hilog.info(0x0001, TAG, `params code: ${params.code}`)
if (params.code !== 200) {
this.pathStack.pop()
}
hilog.info(0x0001, TAG, `params cardType: ${params.cardType}`)
if (params.cardInfo?.front !== undefined) {
this.cardDataSource.push(params.cardInfo?.front)
}

if (params.cardInfo?.back !== undefined) {
this.cardDataSource.push(params.cardInfo?.back)
}

if (params.cardInfo?.main !== undefined) {
this.cardDataSource.push(params.cardInfo?.main)
}
hilog.info(0x0001, TAG, `params cardInfo front: ${JSON.stringify(params.cardInfo?.front)}`)
hilog.info(0x0001, TAG, `params cardInfo back: ${JSON.stringify(params.cardInfo?.back)}`)
})
})
}
.width('100%')
.height('100%')
}
.width('100%')
.height('100%')
.hideTitleBar(true)
}

@Builder
cardDataShowBuilder() {
List() {
ForEach(this.cardDataSource, (cardData: Record<string, string>) => {
ListItem() {
Column() {
Image(cardData.cardImageUri)
.objectFit(ImageFit.Contain)
.width(100)
.height(100)

Text(JSON.stringify(cardData))
.width('100%')
.fontSize(12)
}
}
})
}
.listDirection(Axis.Vertical)
.alignListItem(ListItemAlign.Center)
.margin({
top: 50
})
.width('100%')
.height('100%')
}
}