• c# 新中新二代身份证阅读,包含头像,支持华视


    需要用到dll和文件:

    其中3个dll文件是需要调用的dll,license.dat文件为解压图片的授权文件

    以下是需要用到的dll里面的方法:

            /************************端口类API *************************/
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_SetMaxRFByte", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_SetMaxRFByte(int iPort, byte ucByte, int iIfOpen);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_GetCOMBaud", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_GetCOMBaud(int iPort, ref uint puiBaudRate);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_SetCOMBaud", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_SetCOMBaud(int iPort, uint uiCurrBaud, uint uiSetBaud);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_OpenPort", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_OpenPort(int iPort);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_ClosePort", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_ClosePort(int iPort);
    
            /**************************SAM类函数 **************************/
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_ResetSAM", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_ResetSAM(int iPort, int iIfOpen);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_GetSAMStatus", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_GetSAMStatus(int iPort, int iIfOpen);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_GetSAMID", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_GetSAMID(int iPort, ref byte pucSAMID, int iIfOpen);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_GetSAMIDToStr", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_GetSAMIDToStr(int iPort, ref byte pcSAMID, int iIfOpen);
    
            /*************************身份证卡类函数 ***************************/
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_StartFindIDCard", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_StartFindIDCard(int iPort, ref byte pucIIN, int iIfOpen);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_SelectIDCard", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_SelectIDCard(int iPort, ref byte pucSN, int iIfOpen);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_ReadBaseMsg", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_ReadBaseMsg(int iPort, IntPtr pucCHMsg, ref uint puiCHMsgLen, IntPtr pucPHMsg,
                ref uint puiPHMsgLen, int iIfOpen);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_ReadIINSNDN", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_ReadIINSNDN(int iPort, ref byte pucIINSNDN, int iIfOpen);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_ReadBaseMsgToFile", CharSet = CharSet.Ansi,
                SetLastError = true)]
            public static extern int Syn_ReadBaseMsgToFile(int iPort, ref byte pcCHMsgFileName, ref uint puiCHMsgFileLen,
                ref byte pcPHMsgFileName, ref uint puiPHMsgFileLen, int iIfOpen);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_ReadIINSNDNToASCII", CharSet = CharSet.Ansi,
                SetLastError = true)]
            public static extern int Syn_ReadIINSNDNToASCII(int iPort, ref byte pucIINSNDN, int iIfOpen);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_ReadNewAppMsg", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_ReadNewAppMsg(int iPort, ref byte pucAppMsg, ref uint puiAppMsgLen, int iIfOpen);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_GetBmp", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_GetBmp(string Wlt_File, int iPort);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_ReadMsg", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_ReadMsg(int iPortID, int iIfOpen, ref IDCardData pIDCardData);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_FindReader", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_FindReader();
    
            /***********************设置附加功能函数 ************************/
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_SetPhotoPath", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_SetPhotoPath(int iOption, ref byte cPhotoPath);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_SetPhotoType", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_SetPhotoType(int iType);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_SetPhotoName", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_SetPhotoName(int iType);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_SetSexType", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_SetSexType(int iType);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_SetNationType", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_SetNationType(int iType);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_SetBornType", CharSet = CharSet.Ansi, SetLastError = true)]
            public static extern int Syn_SetBornType(int iType);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_SetUserLifeBType", CharSet = CharSet.Ansi,
                SetLastError = true)]
            public static extern int Syn_SetUserLifeBType(int iType);
    
            [DllImport("idCardDll\SynIDCardAPI.dll", EntryPoint = "Syn_SetUserLifeEType", CharSet = CharSet.Ansi,
                SetLastError = true)]
            public static extern int Syn_SetUserLifeEType(int iType, int iOption);
    
            [DllImport("idCardDll\WltRS.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
            static extern int GetBmp(string pucPHMsg, int intf);
    接口函数

    读取身份证信息分两个阶段,第一个阶段是获取基本信息,第二个阶段是获取图片信息

    获取基本信息很简单,直接调用dll的方法就可以完成,部分代码如下:

                int status = 1;//默认为找不到身份证
                try
                {
                    //先查找读卡器
                    int i, nRet;
                    i = Syn_FindReader();
                    //只支持usb
                    if (i > 1000)
                    {
                        var nPort = i;
                        if (Syn_OpenPort(nPort) == 0)
                        {
                            Thread.Sleep(5);
                            if (Syn_SetMaxRFByte(nPort, 80, 0) == 0)
                            {
                                Thread.Sleep(5);
                                byte[] pucIIN = new byte[4];
                                byte[] pucSN = new byte[8];
                                IDCardData cardMsg = new IDCardData();
                                nRet = Syn_StartFindIDCard(nPort, ref pucIIN[0], 0); //找卡
                                nRet = Syn_SelectIDCard(nPort, ref pucSN[0], 0); //选卡
                                string cardStr = new string(' ', 256); //身份证基本信息返回长度为256
                                string imgMsg = new string(' ', 1024); //身份证图片信息返回长度为1024
                                IntPtr msg = Marshal.StringToHGlobalAnsi(cardStr); //身份证基本信息
                                IntPtr img = Marshal.StringToHGlobalAnsi(imgMsg); //身份证图片
                                uint mLen = 0;
                                uint iLen = 0;
                                nRet = Syn_ReadBaseMsg(nPort, msg, ref mLen, img, ref iLen, 0);
                                if (nRet == 0)
                                {
                                    Syn_ClosePort(nPort);
                                    string card = Marshal.PtrToStringUni(msg);
                                    char[] cartb = card.ToCharArray();
                                    cardMsg.Name = (new string(cartb, 0, 15)).Trim();
                                    cardMsg.Sex = new string(cartb, 15, 1);
                                    cardMsg.Nation = new string(cartb, 16, 2);
                                    cardMsg.Born = new string(cartb, 18, 8);
                                    cardMsg.Address = (new string(cartb, 26, 35)).Trim();
                                    cardMsg.IDCardNo = new string(cartb, 61, 18);
                                    cardMsg.GrantDept = (new string(cartb, 79, 15)).Trim();
                                    cardMsg.UserLifeBegin = new string(cartb, 94, 8);
                                    cardMsg.UserLifeEnd = new string(cartb, 102, 8);
    获取基本信息

    获取图片方法有点麻烦,首先通过Syn_ReadBaseMsg方法返回的图片指针和长度获取的字节信息:

    byte[] data=new byte[iLen];
    Marshal.Copy(img,data,0,data.Length);
    View Code

    将这个获取到的字节信息保存为文件,注意,这里的文件不是图片文件,而是一个wlt类型文件,如果需要获取图片,那么还需要通过GetBmp方法做转换

            private static string GetImageBase64Str(byte[] data, string idCardNo)
            {
                if (!CheckLicense()) return string.Empty;//license.dat文件失败,那么就不能去获取文件
                var wltFileName = Path.Combine(_imageDirPath,
                    string.Format("{0}.wlt", idCardNo));
                if (File.Exists(wltFileName))
                {
                    File.Delete(wltFileName);
                }
                using (FileStream fs = new FileStream(wltFileName, FileMode.Create))
                {
                    fs.Write(data, 0, data.Length);
                    fs.Close();
                }
                var nRet = GetBmp(wltFileName, 2);
                if (nRet == 1)
                {
                  //  Thread.Sleep(200);
                    string bmpFileName = Path.Combine(_imageDirPath,
                        string.Format("{0}.bmp", idCardNo));
                    if (File.Exists(bmpFileName))
                    {
                        var str = GetFileBase64Str(bmpFileName);
                       // File.Delete(bmpFileName);
                        return str;
                    }
                }
                return string.Empty;
            }
    View Code

    代码中将图片信息转换为了base64字符串。

    注意:

      1.由于GetBmp调用了sdtapi.dll中的方法,所以在之前要先要关闭读取的端口,不然会报错。(这是网上用户提醒的,我没有测试过不关闭的情况)

      2.GetBmp方法会在wlt文件的当前目录下生成一个同名的bmp文件,这个文件就是身份证图片文件

      3.获取图片方法需要厂家的授权文件,我用的dll和授权文件都是新中新的,其中授权文件为license.dat,这个文件必须存放在C盘根目录下,并且不能改名,不然读取会出错

            //检测授权文件
            private static bool CheckLicense()
            {
                var licenceFile = @"c:license.dat";
                var localFile = @"idCardDlllicense.dat";
                try
                {
                    if (!File.Exists(licenceFile))
                    {
                        //不存在,拷贝文件过去
                        File.Copy(localFile,licenceFile,true);
                        return true;
                    }
                    //文件存在,需要判断数据是否一致
                    string local = string.Empty;
                    string license = string.Empty;
                    using (FileStream fs = new FileStream(localFile, FileMode.Open, FileAccess.Read))
                    {
                        using (StreamReader sr = new StreamReader(fs))
                        {
                            local = sr.ReadToEnd();
                        }
                    }
                    using (FileStream fs = new FileStream(licenceFile, FileMode.Open, FileAccess.Read))
                    {
                        using (StreamReader sr = new StreamReader(fs))
                        {
                            license = sr.ReadToEnd();
                        }
                    }
                    if (local == license)
                    {
                        return true;
                    }
                    else
                    {
                        File.Copy(localFile, licenceFile, true);
                        return true;
                    }
                }
                catch (Exception ex)
                {
                    //"判断license失败,不能去获取图片";
                    return false;
                }
    
            }
    拷贝检测授权文件

    在转换图片之前先判断授权文件,成功在执行转换操作。

    最终结果是将信息存储IDCardData结构体中,图片信息转换为base64str。

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        public struct IDCardData
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string Name; //姓名   
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
            public string Sex; //性别
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
            public string Nation; //名族
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 18)]
            public string Born; //出生日期
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 72)]
            public string Address; //住址
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 38)]
            public string IDCardNo; //身份证号
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string GrantDept; //发证机关
    
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 18)]
            public string UserLifeBegin; // 有效开始日期
    
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 18)]
            public string UserLifeEnd; // 有效截止日期
    
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 38)]
            public string reserved; // 保留
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
            public string PhotoBase64Str; // 照片路径
        }
    身份证结构

    WltRS.dll一定要新一点的,我以前用的是2007年的,在转换头像的时候总是报错,找了一个新的,是2012年的,就好了。

    以下是我写的一个demo,可以直接调用获取,包含了32位和64的驱动

    https://gitee.com/sczmzx/IdCardReaderHelper/tree/master/IdCardReaderHelper

  • 相关阅读:
    Mac os下安装pycurl
    Mac os 10.9下面配置JAVA_HOME
    同步,异步,阻塞,非阻塞
    Python处理XML
    Apriori算法在购物篮分析中的运用
    Python抓取双色球数据
    为什么这么多Python框架
    Caffe + Ubuntu 14.04 64bit + CUDA 6.5 配置说明
    ubuntu 开机自动挂载分区
    VIM 配置随手记
  • 原文地址:https://www.cnblogs.com/sczmzx/p/8868391.html
Copyright © 2020-2023  润新知