二代身份证读取-微调版

简介: 原文:二代身份证读取-微调版说起微调其实就是对 上一篇文章 今天意外和身份证结缘 中提到的代码码放和调用一些巧妙的用法(至少小鬼觉得很有意思很巧妙)。 为什么有必要在写一篇 写的理由千千万;不写的理由万万千。
原文: 二代身份证读取-微调版

说起微调其实就是对 上一篇文章 今天意外和身份证结缘 中提到的代码码放和调用一些巧妙的用法(至少小鬼觉得很有意思很巧妙)。

为什么有必要在写一篇 写的理由千千万;不写的理由万万千。对于小鬼来说就是:我吃饱了,撑着了,该找点事做了。于是神情恍惚,目光呆滞的敲着键盘,陶醉的望着跳动的光标,嘴角上扬。

   

 

IDCardReader
 #region Using
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
#endregion

/// <summary>
/// 用于获取二代身份证的基本信息(包括图片)
/// 调用时确保 由厂商提供的API的动态链接库等及lic文件
/// 设备 精伦电子公司的iDR200 或 iDR210 型号测试通过
/// 获取的头像图片在应用程序目录下“photo.bmp”文件
/// </summary>
public class IDCardReader
{
#region DllImport
[DllImport("sdtapi.dll")]
private static extern int InitComm(int iPort);//初始化

[DllImport("sdtapi.dll")]
private static extern int CloseComm();//关闭端口

[DllImport("sdtapi.dll")]
private static extern int Authenticate();//卡认证

[DllImport("sdtapi.dll")]//读取数据,推荐使用
private static extern int ReadBaseInfos(
StringBuilder Name,
StringBuilder Gender,
StringBuilder Folk,
StringBuilder BirthDay,
StringBuilder Code,
StringBuilder Address,
StringBuilder Agency,
StringBuilder ExpireStart,
StringBuilder ExpireEnd);

[DllImport("kernel32.dll")]
private static extern int Beep(int dwFreq, int dwDuration);//用来大吼一声
#endregion

public event Action<ReadCardCompletedEventArgs> ReadCardCompleted;
public event Action<string> OnError;

/// <summary>
/// 获取身份证信息.
/// 如果成功就促发ReadCardCompleted事件,事件参数包含相关信息;
/// 否则促发OnError事件.
/// </summary>
public void ReadCard()
{
StringBuilder Name = new StringBuilder(31);
StringBuilder Gender = new StringBuilder(3);
StringBuilder Folk = new StringBuilder(10);
StringBuilder BirthDay = new StringBuilder(9);
StringBuilder Code = new StringBuilder(19);
StringBuilder Address = new StringBuilder(71);
StringBuilder Agency = new StringBuilder(31);
StringBuilder ExpireStart = new StringBuilder(9);
StringBuilder ExpireEnd = new StringBuilder(9);

//打开端口
int intOpenRet = 0;
for (int i = 1001; i < 1004; i++)
{
intOpenRet = InitComm(i);

if (intOpenRet == 1)
break;

}
if (intOpenRet != 1)
{
if (OnError != null) OnError("阅读机具未连接");
return;
}
//卡认证
int intReadRet = Authenticate();
if (intReadRet != 1)
{
if (OnError != null) OnError("卡认证失败");

CloseComm();
return;
}

//ReadBaseInfos(推荐使用)
int intReadBaseInfosRet = ReadBaseInfos(
Name, Gender, Folk, BirthDay,
Code, Address, Agency,
ExpireStart, ExpireEnd);

if (intReadBaseInfosRet == 0)
{
if (OnError != null) OnError("读卡错误");

CloseComm();
return;
}

Beep(2047, 200);
ReadCardCompletedEventArgs args = new ReadCardCompletedEventArgs();
args.Code = Code.ToString().Trim();
args.Name = Name.ToString().Trim();
args.Gender = Gender.ToString().Trim();
args.Folk = Folk.ToString().Trim();
args.BirthDay = BirthDay.ToString().Trim();
args.Address = Address.ToString().Trim();
args.Agency = Agency.ToString().Trim();
args.ExpireStart = ExpireStart.ToString().Trim();
args.ExpireEnd = ExpireEnd.ToString().Trim();
args.PhotoPath = Directory.GetCurrentDirectory() + "\\photo.bmp";

CloseComm();

if (ReadCardCompleted != null)
{
this.ReadCardCompleted(args);
}
}
}

/// <summary>
/// ReadCardCompleted事件参数类
/// 包含身份证基本信息和图片
/// </summary>
public class ReadCardCompletedEventArgs : EventArgs
{
public String Name { get; set; }
/// <summary>
/// 性别
/// </summary>
public String Gender { get; set; }
/// <summary>
/// 民族
/// </summary>
public String Folk { get; set; }

public String BirthDay { get; set; }
/// <summary>
/// 身份证号
/// </summary>
public String Code { get; set; }

public String Address { get; set; }
/// <summary>
/// 发证机关
/// </summary>
public String Agency { get; set; }

public String ExpireStart { get; set; }

public String ExpireEnd { get; set; }

public String PhotoPath { get; set; }
}

代码没有什么改动 就换了一下名字 让编程生活体验更好一点。

当时为什么这样写? 这个问题是问这么写有什么好处。现阶段我只能说习惯这样写。

对了,模模糊糊感觉为了好异步处理这个类的实例。

为什么要处理 异步处理这个类的实例? 因为外部设备运行有一个响应时间,这个响应时间有长有短,不易控制,还容易界面无法响应。

这样界面就感觉卡卡的,用户体验也不好。这样的软件还容易被淘汰掉。得妥善解决这一问题!

   异步调用是关键。

            reader.Value.ReadCardCompleted += (args) =>
{
this.txtAddress.Text = args.Address;
this.txtAgency.Text = args.Agency;
this.txtBirthDay.Text = args.BirthDay;
this.txtCode.Text = args.Code;
this.txtExpireEnd.Text = args.ExpireEnd;
this.txtExpireStart.Text = args.ExpireStart;
this.txtFolk.Text = args.Folk;
this.txtGender.Text = args.Gender;
this.txtName.Text = args.Name;

this.picboxSignle.LoadAsync(args.PhotoPath);
};

//reader.Value.ReadCard();
Action delegateReader = () => reader.Value.ReadCard();
delegateReader.BeginInvoke(null, null);

这里用到了委托的异步调用, 明显改善了程序的性能和用户体验。

这里只是写了一种情况  当然其他具体情况 请看官们斟酌了。
 

 

 

namespace ReadCard
{
#region Using
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
#endregion

/// <summary>
/// 用于获取二代身份证的基本信息(包括图片)
/// 调用时确保 由厂商提供的API的动态链接库等及lic文件
/// 设备 精伦电子公司的iDR200 或 iDR210 型号测试通过
/// 获取的头像图片在应用程序目录下“photo.bmp”文件
/// </summary>
public class IDCardReader
{
#region DllImport
[DllImport("sdtapi.dll")]
private static extern int InitComm(int iPort);//初始化

[DllImport("sdtapi.dll")]
private static extern int CloseComm();//关闭端口

[DllImport("sdtapi.dll")]
private static extern int Authenticate();//卡认证

[DllImport("sdtapi.dll")]//读取数据,推荐使用
private static extern int ReadBaseInfos(
StringBuilder Name,
StringBuilder Gender,
StringBuilder Folk,
StringBuilder BirthDay,
StringBuilder Code,
StringBuilder Address,
StringBuilder Agency,
StringBuilder ExpireStart,
StringBuilder ExpireEnd);

[DllImport("kernel32.dll")]
private static extern int Beep(int dwFreq, int dwDuration);//用来大吼一声
#endregion

public event Action<ReadCardCompletedEventArgs> ReadCardCompleted;
public event Action<string> OnError;

#region 参考代码
//enum ERetReadBaseInfos
//{
// 正确 = 1,
// 读卡错误 = 0,
// 没有最新住址信息 = 2,
// 相片解码错误 = -1,
// wlt文件后缀错误 = -2,
// wlt文件打开错误 = -3,
// wlt文件格式错误 = -4,
// 软件未授权 = -5,
// 无效参数 = -11,
//}
#endregion
/// <summary>
/// 获取身份证信息.
/// 如果成功就促发ReadCardCompleted事件,事件参数包含相关信息;
/// 否则促发OnError事件.
/// </summary>
public void ReadCard()
{
StringBuilder Name = new StringBuilder(31);
StringBuilder Gender = new StringBuilder(3);
StringBuilder Folk = new StringBuilder(10);
StringBuilder BirthDay = new StringBuilder(9);
StringBuilder Code = new StringBuilder(19);
StringBuilder Address = new StringBuilder(71);
StringBuilder Agency = new StringBuilder(31);
StringBuilder ExpireStart = new StringBuilder(9);
StringBuilder ExpireEnd = new StringBuilder(9);

//打开端口
int intOpenRet = 0;
for (int i = 1001; i < 1004; i++)
{
intOpenRet = InitComm(i);

if (intOpenRet == 1)
break;

}
if (intOpenRet != 1)
{
if (OnError != null) OnError("阅读机具未连接");
return;
}
//卡认证
int intReadRet = Authenticate();
if (intReadRet != 1)
{
if (OnError != null) OnError("卡认证失败");

CloseComm();
return;
}

//ReadBaseInfos(推荐使用)
int intReadBaseInfosRet = ReadBaseInfos(
Name, Gender, Folk, BirthDay,
Code, Address, Agency,
ExpireStart, ExpireEnd);

if (intReadBaseInfosRet == 0)
{
if (OnError != null) OnError("读卡错误");

CloseComm();
return;
}

Beep(2047, 200);
ReadCardCompletedEventArgs args = new ReadCardCompletedEventArgs();
args.Code = Code.ToString().Trim();
args.Name = Name.ToString().Trim();
args.Gender = Gender.ToString().Trim();
args.Folk = Folk.ToString().Trim();
args.BirthDay = BirthDay.ToString().Trim();
args.Address = Address.ToString().Trim();
args.Agency = Agency.ToString().Trim();
args.ExpireStart = ExpireStart.ToString().Trim();
args.ExpireEnd = ExpireEnd.ToString().Trim();
args.PhotoPath = Directory.GetCurrentDirectory() + "\\photo.bmp";

CloseComm();

if (ReadCardCompleted != null)
{
this.ReadCardCompleted(args);
}
}
}

/// <summary>
/// ReadCardCompleted事件参数类
/// 包含身份证基本信息和图片
/// </summary>
public class ReadCardCompletedEventArgs : EventArgs
{
public String Name { get; set; }
/// <summary>
/// 性别
/// </summary>
public String Gender { get; set; }
/// <summary>
/// 民族
/// </summary>
public String Folk { get; set; }

public String BirthDay { get; set; }
/// <summary>
/// 身份证号
/// </summary>
public String Code { get; set; }

public String Address { get; set; }
/// <summary>
/// 发证机关
/// </summary>
public String Agency { get; set; }

public String ExpireStart { get; set; }

public String ExpireEnd { get; set; }

public String PhotoPath { get; set; }
}
}
目录
相关文章
|
1月前
|
编解码 文字识别 测试技术
3000 字带你了解Claude3 视觉能力,OCR, 菜单识别统统能搞定!
五大任务,带你了解Claude3的视觉能力有多强 2024 年 3 月 4 日,Anthropic 震撼发布了全新的多模态模型——Claude 3。据该公司介绍,无论是语言处理还是视觉识别任务,Claude 3 都展现出了超越同类竞争产品(例如配备视觉功能的 GPT-4)的卓越性能。
101 0
|
3月前
|
人工智能 搜索推荐 物联网
InstantID:一张照片,无需训练,秒级个人写真生成
InstantID 是由InstantX项目组推出的一种SOTA的tuning-free方法,只需单个图像即可实现 ID 保留生成,并支持各种下游任务。
|
1月前
|
文字识别 负载均衡 安全
文字识别OCR常见问题之通用识别和手写体识别直接合并调用如何解决
文字识别OCR(Optical Character Recognition)技术能够将图片或者扫描件中的文字转换为电子文本。以下是阿里云OCR技术使用中的一些常见问题以及相应的解答。
35 4
|
1月前
|
文字识别 API 开发工具
文字识别OCR常见问题之滴滴行程单无法识别(png上传)如何解决
文字识别OCR(Optical Character Recognition)技术能够将图片或者扫描件中的文字转换为电子文本。以下是阿里云OCR技术使用中的一些常见问题以及相应的解答。
24 2
|
5月前
|
语音技术
同一个语音为什么识别结果还不一致的,有大佬知道原因吗(Paraformer语音识别-中文-通用-16k-离线-large-热词版)
模型speech_paraformer-large-contextual_asr_nat-zh-cn-16k-common-vocab8404,在线体验同一个语音识别结果不一致(https://modelscope.cn/models/damo/speech_paraformer-large-contextual_asr_nat-zh-cn-16k-common-vocab8404/summary)
158 0
|
7月前
|
自然语言处理 数据可视化 PyTorch
双卡3090消费级显卡推理微调OpenBuddy-LLaMA2-70B最佳实践
9月4日,OpenBuddy发布700亿参数跨语言大模型 OpenBuddy-LLaMA2-70B,并以可商用的形态全面开源!现在已经全面上架魔搭ModelScope社区。
双卡3090消费级显卡推理微调OpenBuddy-LLaMA2-70B最佳实践
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
LLM系列 | 01: 亲测ChatGPT最强竞品Claude,注册简单、免手机号
今天这篇小作文主要还是围绕着ChatGPT、Claude和文心一言进行评测
|
11月前
|
文字识别 UED
身份证OCR接口:提高录入效率+识别信息造假
现在的身份证登记多采用人工录入方式,这样做不仅费时而且效率很低。如何利用新兴的身份证OCR接口证件识别技术,快速、高效、完整地录入证件信息,并对其进行相应的管控与核验,已成为许多信息系统亟待解决的问题。
107 0
|
11月前
|
存储 文字识别 小程序
小程序识别身份证 银行卡 营业执照 驾照 小程序OCR图片识别
小程序识别身份证 银行卡 营业执照 驾照 小程序OCR图片识别
134 0
|
移动开发 文字识别 开发工具
iOS小技能: OCR 之银行卡/身份证信息识别(免费次数无限)
1. 功能:扫描银行卡识别信息( 银行名称、 银行卡号)并截取银行卡图像 2. 应用场景:快速填充银行卡号的场景,比如商户进件、实名认证
329 0
iOS小技能: OCR 之银行卡/身份证信息识别(免费次数无限)