# ID_Card_OCR
**Repository Path**: flaychuang/ID_Card_OCR
## Basic Information
- **Project Name**: ID_Card_OCR
- **Description**: 核心识别代码基于 https://github.com/XieZhiFa/IdCardOCR在此基础上重新搭建了识别界面支持自动扫描、拍照扫描、图库图片扫描,仅支持竖屏
- **Primary Language**: Android
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 129
- **Forks**: 58
- **Created**: 2019-07-22
- **Last Updated**: 2025-06-18
## Categories & Tags
**Categories**: image-processing, cv, android-modules
**Tags**: None
## README
#### 项目说明
本项目核心识别代码基于 https://github.com/XieZhiFa/IdCardOC
在此基础上重新搭建了识别界面支持自动扫描、拍照扫描、图库图片扫描,
仅支持竖屏
#### 首页
#### 身份证正面
#### 身份证反面
#### Application中初始化
    LibraryInitOCR.initOCR(context);
#### 调用扫描界面
    Bundle bundle = new Bundle();
    bundle.putBoolean("saveImage",
    binding.saveImage.getSelectedItemPosition() == 0 ? true : false); //是否保存识别图片 
	bundle.putBoolean("showSelect", true); //是否显示选择图片 
	bundle.putBoolean("showCamera", true); //显示图片界面是否显示拍照(驾照选择图片识别率比扫描高)
    bundle.putInt("requestCode", REQUEST_CODE); // requestCode
    bundle.putInt("type", binding.type.getSelectedItemPosition()); //0身份证, 1驾驶证 
	LibraryInitOCR.startScan(context, bundle);
    
    //如果您不想集成aar, 那么可以通过隐式意图拉起示例中的扫描界面 
	boolean isSave = binding.tip.getVisibility() == View.GONE; 
	//身份证:com.msd.ocr.idcard.ICVideo, 驾驶证:com.msd.ocr.idcard.id.DIVideoActivity 
	Intent intent = new Intent("com.msd.ocr.idcard.ICVideo"); 
	intent.putExtra("saveImage",isSave);//是否保存图片
	intent.putExtra("showSelect",true);//是否显示选择图片
	bundle.putBoolean("showCamera", true);//显示图片界面是否显示拍照(驾照选择图片识别率比扫描高)
    intent.addCategory(getPackageName());//调用demo中的扫描界面使用:
    com.tomcat.ocr.idcard startActivityForResult(intent, REQUEST_CODE);
	
	//两种方式,返回的结果都是一样的. 但是选择图片的时候头像暂时不能提前.
#### 返回结果
	@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == REQUEST_CODE && resultCode == RESULT_OK){
            String result = data.getStringExtra("OCRResult");
            try {
                JSONObject jo = new JSONObject(result);
                StringBuffer sb = new StringBuffer();
                sb.append(String.format("正面 = %s\n", jo.opt("type")));
                sb.append(String.format("姓名 = %s\n", jo.opt("name")));
                sb.append(String.format("性别 = %s\n", jo.opt("sex")));
                sb.append(String.format("民族 = %s\n", jo.opt("folk")));
                sb.append(String.format("日期 = %s\n", jo.opt("birt")));
                sb.append(String.format("号码 = %s\n", jo.opt("num")));
                sb.append(String.format("住址 = %s\n", jo.opt("addr")));
                sb.append(String.format("签发机关 = %s\n", jo.opt("issue")));
                sb.append(String.format("有效期限 = %s\n", jo.opt("valid")));
                sb.append(String.format("整体照片 = %s\n", jo.opt("imgPath")));
                sb.append(String.format("头像路径 = %s\n", jo.opt("headPath")));
                sb.append("\n驾照专属字段\n");
                sb.append(String.format("国家 = %s\n", jo.opt("nation")));
                sb.append(String.format("初始领证 = %s\n", jo.opt("startTime")));
                sb.append(String.format("准驾车型 = %s\n", jo.opt("drivingType")));
                sb.append(String.format("有效期限 = %s\n", jo.opt("registerDate")));
                binding.textview.setText(sb.toString());
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
#### aar集成方法
将文件aar文件复制到 libs目录下, 然后在build.gradle中增加:
    android{
        repositories {
            flatDir {
                dirs 'libs'
            }
        }
        manifestPlaceholders = [
            //debug.keystore生成, 正式包需要重新生成.
            "OCR_API_KEY" : "26f1f6a0d4d7cb0dd0e9b28f4cedef83"    
        ]
        ndk {
            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
        }
    }
    dependencies {
        implementation fileTree(include: ['*.jar'], dir: 'libs')
        implementation (name: 'library-ocr-1.0.4-SNAPSHOT', ext: 'aar')
        
        //使用OCR aar包 图片选择需要依赖另外一个库
        implementation 'com.squareup.picasso:picasso:2.4.0'
        implementation(name: 'library-multi-image-selector-1.0.5-SNAPSHOT', ext: 'aar')
        
    }
#### 自定义识别框方式集成
如果当前扫描界面无法满足,您可以自己开发相机预览界面,使用以下API进行识别. 
    //1. Application中初始化
    LibraryInitOCR.initOCR(context); 
    
    //2. 初始化解码器
    /**
     * 解码器初始化, 如果需要保存图片, 需要在调用向系统审核SDCard读写权限.
     * @param context   Activity
     * @param handler   接收解码消息
     * @param isSaveImage   是否保存图片
     */
    public static void initDecode(Context context, Handler handler, boolean isSaveImage)
    //3. 开始解码
    /**
     * 开始解码, 将相机预览数据传递到这里来, onPreviewFrame(byte[] data, Camera camera)
     * @param rect  预览框对象
     * @param previewWidth  界面预览宽
     * @param previewHeight 界面预览高
     * @param data  相机预览数据
     */
    public static void decode(Rect rect, int previewWidth, int previewHeight, byte[] data)
    
    /**
     * 识别选择的身份证图片(注意提前申请读写权限)
     * @param filePath  文件路径
     */
    public static void decode(String filePath)
    //4.在Activity onDestroy 释放资源
    /**
     * 释放资源
     */
    public static void closeDecode()
    
    
    
    //解码结果通过handler 接收
    switch (msg.what){
        //解码成功
        case LibraryInitOCR.DECODE_SUCCESS: {
            Intent intent = (Intent) msg.obj;
            String result = intent.getStringExtra("OCRResult");
            String headImg = intent.getStringExtra("headImg");
            String fullImg = intent.getStringExtra("fullImg");
            break;
        }
        //解码失败
        case LibraryInitOCR.DECODE_FAIL:{
            break;
        }
        //未授权
        case LibraryInitOCR.DECODE_UNAUTHORIZED:{
            break;
        }
        //提示重新聚焦
        case LibraryInitOCR.DECODE_AUTO_FOCUS:{
            break;
        }
    }
    
    
#### 混淆排除
    #排除身份证识别库本地方法
    -keep class com.ym.idcard.reg.** {*;}
    -keep class com.ym.ocr.img.** {*;}
    -keep class hotcard.doc.reader.** {*;}
    -keep class com.msd.ocr.idcard.LibraryInitOCR {*;}
    
    -keepclassmembers class * {
        native ;
    }
    -keepclasseswithmembernames class * {
        native ;
    }
  
#### 证示例图
对着电脑扫描识别率会比较低, 建议使用身份证原件做测试.
