android身份证自动识别

来源:互联网 发布:淘宝商品美化 编辑:程序博客网 时间:2024/05/21 14:49
android身份证拍照识别:
    市场上身份证识别一般是通过第三方的公司专门做ocr识别的通过接口的形式对身份证进行识别,在此我主要介绍一下不通过第三方公司的接口该如何实现身份证自动识别.
1.拍照识别身份证:
    首先通过自定义相机进行拍照,(注:由于上一篇已经对自定义相机拍照功能的实现做了介绍以及上传了详细代码,在这里就不做介绍了)将拍照的图片通过jni调用so库将图片传给切片so库对图片进行切片.将身份证号码单独切出来,将单独切出的身份证号码图片传给识别so库进行识别,在识别的时候我们首先需要一个训练库,训练库里面包含身份证的单个字符,其实识别的准备率就是看训练库里面包含的所有场景:
 android通过jni调用so的接口(注:com.qdym.idcardcode.utils接口包名必须是这个以及类名也必须是IDCardRecognition
因为so里面提供的接口名是跟着包名及类名一致的
):
package com.qdym.idcardcode.utils;/** * 作者:zhongshuiping * <p/> * 工号: ${USER_NAME} */public class IDCardRecognition {    // TODO Auto-generated constructor stub    /* 初始化函数     * 返回:0,说明操作成功    * @param strFilePath 文件路径  示例:D:\CNTK    */    public static native int Init(String strFilePath);    /* 图片匹配切割纠正    * 返回:成功:裁剪后保存的图像路径 失败:返回null    * @param infoData jpg图片信息数据    * @param jpgData jpg图片数据    * @param strCutFile 裁剪后保存的图片路径包含文件名    * @param strIDFile 保存裁剪后的身份证号码区域图片    */    public static native int JpgImgCut(byte[] jpgData, int[] infoData,String strCutFile,String strIDFile);    /* 初始化函数 * 返回:身份证号码,说明操作成功,否则返回null * @param strImgFile 文件路径  示例:D:\CNTK\1.jpg */    public static native String GetIDCard(String strImgFile);    static {        System.loadLibrary("IDCardRecognition");    }}
int Result= IDCardRecognition.JpgImgCut(data,infoData, maximgPath,minimgpath);String IDcardValue=IDCardRecognition.GetIDCard(minimgpath);

2.zip格式文件:
    由于我们需要对身份证进行拍照,拍照下来的图片需要存在手机的文件夹里面,因为身份证涉及到个人信息安全问题,所以在此我将可视化的jpg图片进行zip打包并设置解压密码,并压缩减少存储内存.
加载依赖库:
compile 'net.lingala.zip4j:zip4j:1.3.2'
/*** * zip图片转换 */private void deletefile(){    new AsyncTask<Void, Void, Void>() {        @Override        protected Void doInBackground(Void... p) {            SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd-HH-mm-ss");            String time= format.format(new Date(System.currentTimeMillis()));            String zipPath = newFilePath.substring(0, newFilePath.lastIndexOf(".")) +"_"+time+ ".zip";            Zip4JUtils.zip(newFilePath, zipPath, false, "NoBug");            uploadFile.delete();            return null;        }    }.execute();}
3.定期删除:
    拍照识别后的图片通过zip打包存在手机文件夹对应的目录下的文件进行异步定期删除,
/** * 定期删除图片 */private void deletezip(){    String fileall= FileUtils.saveMaxImgFile();    File  waybillfile=new File(fileall);    File[] files = waybillfile.listFiles();// 读取    getFileName(files);}
/*** * 定时删除文件大图 * 设置三天删除一次 * @param files */private  void getFileName(File[] files) {    if (files != null) {// 先判断目录是否为空,否则会报空指针        for (File file : files) {            if (file.isDirectory()) {                getFileName(file.listFiles());            } else {                String fileName = file.getName();                if (fileName.endsWith(".zip")) {                    try {                        SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd-HH-mm-ss");                        String s =fileName.substring(fileName.lastIndexOf("_")+1,fileName.lastIndexOf(".")).toString().trim();                        Date date1 = format.parse(s);                        String dateString = format.format(new Date(System.currentTimeMillis()));                        Date date2 = format.parse(dateString);                        String ph= FileUtils.saveMaxImgFile()+File.separator+file.getName();                        File fe = new File(ph);                        if (getBetweenDay(date1, date2) >=2) {                            fe.delete();                        }                    } catch (ParseException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }// 当前时间                }            }        }    }}
/** * 计算两个日期相差多少天 * @param date1 * @param date2 * zhongshuiping * @return */public static int getBetweenDay(Date date1, Date date2) {    Calendar d1 = new GregorianCalendar();    d1.setTime(date1);    Calendar d2 = new GregorianCalendar();    d2.setTime(date2);    int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR);    System.out.println("days=" + days);    int y2 = d2.get(Calendar.YEAR);    if (d1.get(Calendar.YEAR) != y2) {        do {            days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);            d1.add(Calendar.YEAR, 1);        } while (d1.get(Calendar.YEAR) != y2);    }    return days;}

4.删除jpg图片:
    通过循环查找文件夹删除jpg图片

/*** * 删除jpg图片 * @param */private  void deleteJpgPic() {    new AsyncTask<Void, Void, Void>() {        @Override        protected Void doInBackground(Void... p) {            String filealljpg=FileUtils.saveMaxImgFile();            File jpgfile=new File(filealljpg);            File[] filesjpg = jpgfile.listFiles();// 读取            if (filesjpg != null) {// 先判断目录是否为空,否则会报空指针                for (File file : filesjpg) {                    if (file.isDirectory()) {                        getFileName(file.listFiles());                    } else {                        String fileName = file.getName();                        if (fileName.endsWith(".jpg")) {                            file.delete();                        }                    }                }            }            return null;        }    }.execute();}


5 base64解密:
     由于身份证涉及到个人信息安全问题,所以这里我默认是base64加密数据,如果需要展示在界面上点击base64解密按钮对数据进行解密.
Google提供的解密依赖库:
compile 'net.iharder:base64:2.3.9'

/**** * base64解密 */base64decrypt.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        try {            if(path!=null){                newoneimag =Base64.decode(newimag);                map= ImageTools.byteToBitmap(newoneimag);                photo_previews.setImageBitmap(map);            }else{                Toast.makeText(MainActivity.this,"图片为空",Toast.LENGTH_LONG).show();            }        } catch (IOException e) {            e.printStackTrace();        }    }});

简单界面展示如下:





以上是android身份证识别的部分代码,具体详细代码如
下:

  http://download.csdn.net/download/androidzsp/10024824(身份证识别demo)
 
http://download.csdn.net/download/androidzsp/10024882(自定义相机demo)