├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── idcard.jks
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── kbyai
│ │ └── idcardrecognition
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── kbyai
│ │ │ └── idcardrecognition
│ │ │ ├── AboutActivity.kt
│ │ │ ├── CameraActivityKt.kt
│ │ │ ├── FaceView.java
│ │ │ ├── MainActivity.kt
│ │ │ ├── ResultActivity.kt
│ │ │ ├── ResultAdapter.java
│ │ │ ├── ResultDataFragment.kt
│ │ │ ├── ResultItem.java
│ │ │ ├── ResultOverviewFragment.kt
│ │ │ ├── ResultViewPagerAdapter.kt
│ │ │ └── Utils.java
│ └── res
│ │ ├── drawable
│ │ ├── ic_about.xml
│ │ ├── ic_camera.xml
│ │ ├── ic_email.xml
│ │ ├── ic_gallery.xml
│ │ ├── ic_github.png
│ │ ├── ic_kby.png
│ │ ├── ic_settings.xml
│ │ ├── ic_skype.png
│ │ ├── ic_telegram.png
│ │ ├── ic_tip.xml
│ │ └── ic_whatsapp.png
│ │ ├── layout
│ │ ├── activity_about.xml
│ │ ├── activity_camera.xml
│ │ ├── activity_camera_kt.xml
│ │ ├── activity_main.xml
│ │ ├── activity_result.xml
│ │ ├── fragment_result_data.xml
│ │ ├── fragment_result_overview.xml
│ │ └── item_result.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── values-night
│ │ └── themes.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── backup_rules.xml
│ │ ├── data_extraction_rules.xml
│ │ └── file_paths.xml
│ └── test
│ └── java
│ └── com
│ └── kbyai
│ └── idcardrecognition
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── libfotoapparat
├── build.gradle
└── fotoapparat-2.7.0.aar
├── libidsdk
├── .gitignore
└── build.gradle
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 | /.idea/
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | ### Our facial recognition algorithm is globally top-ranked by NIST in the FRVT 1:1 leaderboards.
8 | [Latest NIST FRVT evaluation report 2024-12-20](https://pages.nist.gov/frvt/html/frvt11.html)
9 |
10 | 
11 |
12 | #### 🆔 ID Document Liveness Detection - Linux - [Here](https://web.kby-ai.com)
13 | #### 🤗 Hugging Face - [Here](https://huggingface.co/spaces/kby-ai/IDCardRecognition)
14 | #### 📚 Product & Resources - [Here](https://github.com/kby-ai/Product)
15 | #### 🛟 Help Center - [Here](https://docs.kby-ai.com/help/product/id-card-sdk)
16 | #### 💼 KYC Verification Demo - [Here](https://github.com/kby-ai/KYC-Verification-Demo-Android)
17 | #### 🙋♀️ Docker Hub - [Here](https://hub.docker.com/r/kbyai/idcard-recognition)
18 |
19 | # IDCardRecognition-Android
20 | ## Overview
21 |
22 | This repository demonstrates `ID document recognition`, `ID card recognition`, `ID card scanner and reader` `ID document scanner and reader`, `ID Card OCR`, `passport reader` and `passport recognition` technology developed by `KBY-AI`.
23 |
24 | > In this repository, we integrated `KBY-AI`'s `ID document OCR` solution into `Android` native platform.
25 | ## Try the APK
26 |
27 | ### Google Play
28 |
29 |
30 |
31 |
32 |
33 | ## Performance Video
34 | You can visit our YouTube video [here](https://www.youtube.com/watch?v=s3G3MzrdDXI) to see how well our demo app works.
35 | [](https://www.youtube.com/watch?v=s3G3MzrdDXI)
36 |
37 | ## Screenshots
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | ### ◾ID Card Recognition SDK Main Functionalities
46 |
47 | | Surpported ID Type | Functionalities | Release Type |
48 | |------------------|------------------|------------------|
49 | | ID Card | Extracting Information(OCR) | Android(`Kotlin & Java`) |
50 | | Passport | Scanning Barcode | iOS(`Swift & Objectiv-C`) |
51 | | Driver License | Parsing MRZ | Flutter(`Dart`) |
52 | | | Auto Capturing | Web Front-end(`Javascript`) |
53 | | | Scanning QR code | Server-Windows(`Python`) |
54 | | | Supporting 200+ Countries' ID Documents | Server-Linux(`Python`) |
55 | | | Supporting 130+ Languages | |
56 | | | ID Document Detection | |
57 |
58 | ### ◾ID Card Recognition Product List
59 | | No. | Repository | Release Type |
60 | |------------------|------------------|------------------|
61 | | ➡️ | [ID Card Recognition - Android](https://github.com/kby-ai/IDCardRecognition-Android) | Android |
62 | | 2 | [ID Card Recognition - iOS](https://github.com/kby-ai/IDCardRecognition-iOS) | iOS |
63 | | 3 | [ID Card Recognition - Flutter](https://github.com/kby-ai/IDCardRecognition-Flutter) | Flutter |
64 | | 4 | [ID Auto Capture - React](https://github.com/kby-ai/ID-document-capture-React) | Web Front-end |
65 | | 5 | [ID Card Recognition - Windows](https://github.com/kby-ai/IDCardRecognition-Windows) | Server-Windows |
66 | | 6 | [ID Card Recognition - Linux](https://github.com/kby-ai/IDCardRecognition-Docker) | Server-Linux |
67 | | 7 | [ID Card Recognition - C#](https://github.com/kby-ai/IDCardRecognition-CSharp-.NET) | Server-Windows |
68 |
69 | ## SDK License
70 |
71 | - The code line below shows how to update SDK with the `license key`: https://github.com/kby-ai/IDCardRecognition-Android/blob/1db9754a66b0211715ab458a23d3a2dd93f9303d/app/src/main/java/com/kbyai/idcardrecognition/MainActivity.kt#L22-L31
72 | - To request `license key`, please contact us:
73 | 🧙`Email:` contact@kby-ai.com
74 | 🧙`Telegram:` [@kbyai](https://t.me/kbyai)
75 | 🧙`WhatsApp:` [+19092802609](https://wa.me/+19092802609)
76 | 🧙`Discord:` [KBY-AI](https://discord.gg/CgHtWQ3k9T)
77 | 🧙`Teams:` [KBY-AI](https://teams.live.com/l/invite/FBAYGB1-IlXkuQM3AY)
78 |
79 | ## How To Run
80 | ### 1. Placing Library File
81 | Download the `SDK library` file for `Android`(`idsdk.aar`) from [here](https://drive.google.com/file/d/1hys99a7QG7-px_m8DGa9RKqR7wr6E8bS/view?usp=sharing) and put it on the suitable `SDK` folder(folder `libidsdk`).
82 | ### 3. Running the App
83 | Try to build this repo on `Android Studio` by linking real `Android` phone, not `simulator`. Once it works fine, you are ready to integrate our `SDK` to your project.
84 |
85 | ## About SDK
86 |
87 | ### 1. Set up
88 | 1. Download our SDK library file(`idsdk.aar`) from [here](https://drive.google.com/file/d/1hys99a7QG7-px_m8DGa9RKqR7wr6E8bS/view?usp=sharing) and paste it to SDK folder(folder `libidsdk`). Try to build this repo to make sure that SDK works fine by linking real `Android` phone, not `simulator`. Once it works fine, you are ready to integrate our SDK to your project.
89 | And then copy the SDK(folder `libidsdk`) to the `root` folder in your project.
90 |
91 | 2. Add SDK to the project in `settings.gradle`.
92 | ```bash
93 | include ':libidsdk'
94 | ```
95 |
96 | 3. Add dependency to your `build.gradle`.
97 | ```bash
98 | implementation project(path: ':libidsdk')
99 | ```
100 |
101 | ### 2. Initializing the SDK
102 |
103 | - Step One
104 |
105 | To begin, you need to activate the SDK using the `license key` that you have received.
106 | ```kotlin
107 | IDSDK.setActivation("...")
108 | ```
109 |
110 | If activation is successful, SDK would return `SDK_SUCCESS`. Otherwise, it would return an error message.
111 |
112 | - Step Two
113 |
114 | Once activation is successful, you can call initialization function supported by our SDK.
115 | ```kotlin
116 | IDSDK.init(getAssets());
117 | ```
118 | If initialization is successful, SDK would return `SDK_SUCCESS`. Otherwise, it would return an error message.
119 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'org.jetbrains.kotlin.android'
4 | }
5 |
6 | android {
7 | namespace 'com.kbyai.idcardrecognition'
8 | compileSdk 34
9 |
10 | defaultConfig {
11 | applicationId "com.kbyai.idcardrecognition"
12 | minSdk 24
13 | targetSdk 34
14 | versionCode 8
15 | versionName "1.7"
16 |
17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
18 |
19 | ndk {
20 | abiFilters 'arm64-v8a', 'armeabi-v7a'
21 | }
22 | }
23 |
24 | buildTypes {
25 | release {
26 | minifyEnabled false
27 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
28 | }
29 | }
30 | compileOptions {
31 | sourceCompatibility JavaVersion.VERSION_1_8
32 | targetCompatibility JavaVersion.VERSION_1_8
33 | }
34 | kotlinOptions {
35 | jvmTarget = '1.8'
36 | }
37 | }
38 |
39 | dependencies {
40 |
41 | implementation 'androidx.core:core-ktx:1.7.0'
42 | implementation 'androidx.appcompat:appcompat:1.6.1'
43 | implementation 'com.google.android.material:material:1.9.0'
44 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
45 |
46 | implementation project(path: ':libidsdk')
47 |
48 | implementation 'com.itextpdf:itextpdf:5.5.10'
49 |
50 | // PDF library
51 | // implementation 'io.fotoapparat:fotoapparat:2.7.0'
52 | implementation project(path: ':libfotoapparat')
53 |
54 | testImplementation 'junit:junit:4.13.2'
55 | androidTestImplementation 'androidx.test.ext:junit:1.1.5'
56 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
57 | }
--------------------------------------------------------------------------------
/app/idcard.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kby-ai/IDCardRecognition-Android/d0632898f94939b908f857abb91b0ae3a2217f61/app/idcard.jks
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/kbyai/idcardrecognition/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.kbyai.idcardrecognition
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.kbyai.idcardrecognition", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
20 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
37 |
41 |
46 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kbyai/idcardrecognition/AboutActivity.kt:
--------------------------------------------------------------------------------
1 | package com.kbyai.idcardrecognition
2 |
3 | import android.content.Intent
4 | import android.content.pm.ResolveInfo
5 | import android.net.Uri
6 | import android.os.Bundle
7 | import android.widget.TextView
8 | import androidx.appcompat.app.AppCompatActivity
9 | import com.kbyai.idcardrecognition.R
10 |
11 |
12 | class AboutActivity : AppCompatActivity() {
13 | override fun onCreate(savedInstanceState: Bundle?) {
14 | super.onCreate(savedInstanceState)
15 | setContentView(R.layout.activity_about)
16 |
17 | findViewById(R.id.txtMail).setOnClickListener {
18 | val intent = Intent(Intent.ACTION_SEND)
19 | intent.type = "plain/text"
20 | intent.putExtra(Intent.EXTRA_EMAIL, arrayOf("contact@kby-ai.com"))
21 | intent.putExtra(Intent.EXTRA_SUBJECT, "License Request")
22 | intent.putExtra(Intent.EXTRA_TEXT, "")
23 | startActivity(Intent.createChooser(intent, ""))
24 | }
25 |
26 | findViewById(R.id.txtWhatsapp).setOnClickListener {
27 | val general = Intent(Intent.ACTION_VIEW, Uri.parse("https://com.whatsapp/kbyai"))
28 | val generalResolvers: HashSet = HashSet()
29 | val generalResolveInfo: List = packageManager.queryIntentActivities(general, 0)
30 | for (info in generalResolveInfo) {
31 | if (info.activityInfo.packageName != null) {
32 | generalResolvers.add(info.activityInfo.packageName)
33 | }
34 | }
35 |
36 | val telegram = Intent(Intent.ACTION_VIEW, Uri.parse("https://wa.me/19092802609"))
37 | var goodResolver = 0
38 |
39 | val resInfo: List = packageManager.queryIntentActivities(telegram, 0)
40 | if (!resInfo.isEmpty()) {
41 | for (info in resInfo) {
42 | if (info.activityInfo.packageName != null && !generalResolvers.contains(info.activityInfo.packageName)) {
43 | goodResolver++
44 | telegram.setPackage(info.activityInfo.packageName)
45 | }
46 | }
47 | }
48 |
49 | if (goodResolver != 1) {
50 | telegram.setPackage(null)
51 | }
52 | if (telegram.resolveActivity(packageManager) != null) {
53 | startActivity(telegram)
54 | }
55 | }
56 |
57 | findViewById(R.id.txtTelegram).setOnClickListener {
58 | val general = Intent(Intent.ACTION_VIEW, Uri.parse("https://t.com/kbyai"))
59 | val generalResolvers: HashSet = HashSet()
60 | val generalResolveInfo: List = packageManager.queryIntentActivities(general, 0)
61 | for (info in generalResolveInfo) {
62 | if (info.activityInfo.packageName != null) {
63 | generalResolvers.add(info.activityInfo.packageName)
64 | }
65 | }
66 |
67 | val telegram = Intent(Intent.ACTION_VIEW, Uri.parse("https://t.me/kbyai"))
68 | var goodResolver = 0
69 |
70 | val resInfo: List = packageManager.queryIntentActivities(telegram, 0)
71 | if (!resInfo.isEmpty()) {
72 | for (info in resInfo) {
73 | if (info.activityInfo.packageName != null && !generalResolvers.contains(info.activityInfo.packageName)) {
74 | goodResolver++
75 | telegram.setPackage(info.activityInfo.packageName)
76 | }
77 | }
78 | }
79 |
80 | if (goodResolver != 1) {
81 | telegram.setPackage(null)
82 | }
83 | if (telegram.resolveActivity(packageManager) != null) {
84 | startActivity(telegram)
85 | }
86 | }
87 |
88 | findViewById(R.id.txtSkype).setOnClickListener {
89 | val general = Intent(Intent.ACTION_VIEW, Uri.parse("https://com.skype/kbyai"))
90 | val generalResolvers: HashSet = HashSet()
91 | val generalResolveInfo: List = packageManager.queryIntentActivities(general, 0)
92 | for (info in generalResolveInfo) {
93 | if (info.activityInfo.packageName != null) {
94 | generalResolvers.add(info.activityInfo.packageName)
95 | }
96 | }
97 |
98 | val telegram = Intent(Intent.ACTION_VIEW, Uri.parse("https://join.skype.com/invite/OffY2r1NUFev"))
99 | var goodResolver = 0
100 |
101 | val resInfo: List = packageManager.queryIntentActivities(telegram, 0)
102 | if (!resInfo.isEmpty()) {
103 | for (info in resInfo) {
104 | if (info.activityInfo.packageName != null && !generalResolvers.contains(info.activityInfo.packageName)) {
105 | goodResolver++
106 | telegram.setPackage(info.activityInfo.packageName)
107 | }
108 | }
109 | }
110 |
111 | if (goodResolver != 1) {
112 | telegram.setPackage(null)
113 | }
114 | if (telegram.resolveActivity(packageManager) != null) {
115 | startActivity(telegram)
116 | }
117 | }
118 |
119 | findViewById(R.id.txtGitHub).setOnClickListener {
120 | val general = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/kby-ai"))
121 | val generalResolvers: HashSet = HashSet()
122 | val generalResolveInfo: List = packageManager.queryIntentActivities(general, 0)
123 | for (info in generalResolveInfo) {
124 | if (info.activityInfo.packageName != null) {
125 | generalResolvers.add(info.activityInfo.packageName)
126 | }
127 | }
128 |
129 | val telegram = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/kby-ai"))
130 | var goodResolver = 0
131 |
132 | val resInfo: List = packageManager.queryIntentActivities(telegram, 0)
133 | if (!resInfo.isEmpty()) {
134 | for (info in resInfo) {
135 | if (info.activityInfo.packageName != null && !generalResolvers.contains(info.activityInfo.packageName)) {
136 | goodResolver++
137 | telegram.setPackage(info.activityInfo.packageName)
138 | }
139 | }
140 | }
141 |
142 | if (goodResolver != 1) {
143 | telegram.setPackage(null)
144 | }
145 | if (telegram.resolveActivity(packageManager) != null) {
146 | startActivity(telegram)
147 | }
148 | }
149 | }
150 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kbyai/idcardrecognition/CameraActivityKt.kt:
--------------------------------------------------------------------------------
1 | package com.kbyai.idcardrecognition;
2 |
3 | import android.Manifest
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.content.pm.PackageManager
7 | import android.graphics.Rect
8 | import android.os.Bundle
9 | import android.util.Log
10 | import android.util.Size
11 | import androidx.appcompat.app.AppCompatActivity
12 | import androidx.core.app.ActivityCompat
13 | import androidx.core.content.ContextCompat
14 | import com.kbyai.idsdk.IDSDK
15 | import io.fotoapparat.Fotoapparat
16 | import io.fotoapparat.parameter.Resolution
17 | import io.fotoapparat.preview.Frame
18 | import io.fotoapparat.preview.FrameProcessor
19 | import io.fotoapparat.selector.back
20 | import io.fotoapparat.view.CameraView
21 | import org.json.JSONObject
22 |
23 | class CameraActivityKt : AppCompatActivity() {
24 |
25 | val TAG = CameraActivityKt::class.java.simpleName
26 | val PREVIEW_WIDTH = 720
27 | val PREVIEW_HEIGHT = 1280
28 |
29 | private lateinit var cameraView: CameraView
30 | private lateinit var faceView: FaceView
31 | private lateinit var fotoapparat: Fotoapparat
32 | private lateinit var context: Context
33 | private var documenName: String = ""
34 | private var positionRect: Rect = Rect()
35 |
36 | private var recognized = false
37 |
38 | override fun onCreate(savedInstanceState: Bundle?) {
39 | super.onCreate(savedInstanceState)
40 | setContentView(R.layout.activity_camera_kt)
41 |
42 | context = this
43 | cameraView = findViewById(R.id.preview)
44 | faceView = findViewById(R.id.faceView)
45 |
46 | fotoapparat = Fotoapparat.with(this)
47 | .into(cameraView)
48 | .lensPosition(back())
49 | .frameProcessor(FaceFrameProcessor())
50 | .previewResolution { Resolution(PREVIEW_HEIGHT,PREVIEW_WIDTH) }
51 | .build()
52 |
53 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
54 | == PackageManager.PERMISSION_DENIED
55 | ) {
56 | ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 1)
57 | } else {
58 | fotoapparat.start()
59 | }
60 | }
61 |
62 | override fun onResume() {
63 | super.onResume()
64 | recognized = false
65 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
66 | == PackageManager.PERMISSION_GRANTED
67 | ) {
68 | fotoapparat.start()
69 | }
70 | }
71 |
72 | override fun onPause() {
73 | super.onPause()
74 | fotoapparat.stop()
75 | faceView.setDocumentInfos(null, "")
76 | }
77 |
78 | override fun onRequestPermissionsResult(
79 | requestCode: Int,
80 | permissions: Array,
81 | grantResults: IntArray
82 | ) {
83 | super.onRequestPermissionsResult(requestCode, permissions, grantResults)
84 | if (requestCode == 1) {
85 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
86 | == PackageManager.PERMISSION_GRANTED
87 | ) {
88 | fotoapparat.start()
89 | }
90 | }
91 | }
92 |
93 | inner class FaceFrameProcessor : FrameProcessor {
94 |
95 | override fun process(frame: Frame) {
96 |
97 | if(recognized == true) {
98 | return
99 | }
100 |
101 | val bitmap = IDSDK.yuv2Bitmap(frame.image, frame.size.width, frame.size.height, 6)
102 | val result = IDSDK.idcardRecognition(bitmap)
103 |
104 | try {
105 | val jsonResult = JSONObject(result)
106 | val positionObj = jsonResult["Position"] as JSONObject
107 | val hasMrz = jsonResult.has("MRZ")
108 | documenName = jsonResult["Document Name"] as String
109 | val quality = jsonResult["Quality"] as Int
110 | val x1 = positionObj["x1"] as Int
111 | val y1 = positionObj["y1"] as Int
112 | val x2 = positionObj["x2"] as Int
113 | val y2 = positionObj["y2"] as Int
114 | positionRect = Rect(x1, y1, x2, y2)
115 | if (quality > 86 && (documenName != "Unknown" || hasMrz == true)) {
116 | recognized = true
117 |
118 | runOnUiThread {
119 | faceView.setFrameSize(Size(bitmap.width, bitmap.height))
120 | faceView.setDocumentInfos(positionRect, documenName)
121 | }
122 |
123 | runOnUiThread {
124 | ResultActivity.resultString = jsonResult.toString()
125 | val intent = Intent(context, ResultActivity::class.java)
126 | startActivity(intent)
127 | }
128 | }
129 | documenName = documenName + " " + quality
130 | } catch (e1: Exception) {
131 | documenName = ""
132 | positionRect = Rect()
133 | }
134 |
135 | runOnUiThread {
136 | faceView.setFrameSize(Size(bitmap.width, bitmap.height))
137 | faceView.setDocumentInfos(positionRect, documenName)
138 | }
139 | }
140 | }
141 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kbyai/idcardrecognition/FaceView.java:
--------------------------------------------------------------------------------
1 | package com.kbyai.idcardrecognition;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.Rect;
8 | import android.util.AttributeSet;
9 | import android.util.Log;
10 | import android.util.Size;
11 | import android.view.View;
12 |
13 | import androidx.annotation.Nullable;
14 |
15 | import java.util.List;
16 |
17 | public class FaceView extends View {
18 |
19 | private Context context;
20 | private Paint realPaint;
21 | private Paint spoofPaint;
22 |
23 | private Size frameSize;
24 |
25 | private Rect position;
26 |
27 | private String documentName;
28 |
29 | public FaceView(Context context) {
30 | this(context, null);
31 |
32 | this.context = context;
33 | init();
34 | }
35 |
36 | public FaceView(Context context, @Nullable AttributeSet attrs) {
37 | super(context, attrs);
38 | this.context = context;
39 |
40 | init();
41 | }
42 |
43 | public void init() {
44 | setLayerType(View.LAYER_TYPE_SOFTWARE, null);
45 |
46 | realPaint = new Paint();
47 | realPaint.setStyle(Paint.Style.STROKE);
48 | realPaint.setStrokeWidth(3);
49 | realPaint.setColor(Color.GREEN);
50 | realPaint.setAntiAlias(true);
51 | realPaint.setTextSize(50);
52 |
53 | spoofPaint = new Paint();
54 | spoofPaint.setStyle(Paint.Style.STROKE);
55 | spoofPaint.setStrokeWidth(3);
56 | spoofPaint.setColor(Color.RED);
57 | spoofPaint.setAntiAlias(true);
58 | spoofPaint.setTextSize(50);
59 | }
60 |
61 | public void setFrameSize(Size frameSize)
62 | {
63 | this.frameSize = frameSize;
64 | }
65 |
66 | public void setDocumentInfos(Rect position, String documentName)
67 | {
68 | this.position = position;
69 | this.documentName = documentName;
70 | invalidate();
71 | }
72 |
73 | @Override
74 | protected void onDraw(Canvas canvas) {
75 | super.onDraw(canvas);
76 |
77 | if(position != null && !position.isEmpty()) {
78 | float x_scale = this.frameSize.getWidth() / (float)canvas.getWidth();
79 | float y_scale = this.frameSize.getHeight() / (float)canvas.getHeight();
80 |
81 | realPaint.setStrokeWidth(3);
82 | realPaint.setStyle(Paint.Style.FILL_AND_STROKE);
83 | canvas.drawText(documentName, (position.left / x_scale) + 10, (position.top / y_scale) - 30, realPaint);
84 |
85 | realPaint.setStyle(Paint.Style.STROKE);
86 | realPaint.setStrokeWidth(5);
87 |
88 | canvas.drawRect(new Rect((int)(position.left / x_scale), (int)(position.top / y_scale),
89 | (int)(position.right / x_scale), (int)(position.bottom / y_scale)), realPaint);
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kbyai/idcardrecognition/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.kbyai.idcardrecognition
2 |
3 | import android.content.Intent
4 | import android.graphics.Bitmap
5 | import android.os.Bundle
6 | import android.util.Log
7 | import android.widget.Button
8 | import android.widget.TextView
9 | import androidx.appcompat.app.AppCompatActivity
10 | import com.kbyai.idsdk.IDSDK
11 | import org.json.JSONObject
12 | import android.widget.Toast
13 |
14 | class MainActivity : AppCompatActivity() {
15 | companion object {
16 | private val SELECT_PHOTO_REQUEST_CODE = 1
17 | private val IDCARD_RECOGNITION_REQUEST_CODE = 2
18 | }
19 |
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 | setContentView(R.layout.activity_main)
23 |
24 | var ret = IDSDK.setActivation(
25 | "kUWgfFn5kv5ZeJ659tvyW3poZO2xb5llqL/se3g69rVmUJdOuUp8lyAwoeiZe+6e6PeER97sw4zL\n" +
26 | "/rMR0qYVp0nupe6W7TzgQHtjq119BJKVDuxXjbQEyuM29nSEeRVYSwO2htOUEF/V1IH9BIfo33Vc\n" +
27 | "sAg9ohvVuB5DT9BKHXQKevmEmE2AXba2t6ponKAUQ6VwWIX+w1NON8A+6hCoSIDlzVkacbsAp6Kg\n" +
28 | "B0Abfqzbqhz8GG5WNPZlonx7XRNwKlYU+sPo/X6noy1gr7iAAhC+KpWetD2KOWsunyAswkZ5cg2Y\n" +
29 | "WK5/HQXG+h2oGSkjrZj9zH7kGbzzDbn+2qT2jA=="
30 | )
31 | if(ret == IDSDK.SDK_SUCCESS) {
32 | ret = IDSDK.init(this)
33 | }
34 |
35 | findViewById