Skip to content

Commit 2f55a7a

Browse files
committed
Scan face detected by Microblink if available
1 parent bd559a5 commit 2f55a7a

File tree

5 files changed

+52
-16
lines changed

5 files changed

+52
-16
lines changed

app/src/main/java/com/appliedrec/credentials/app/IDCardActivity.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import android.content.Intent;
44
import android.graphics.Bitmap;
55
import android.graphics.BitmapFactory;
6+
import android.net.Uri;
67
import android.os.Bundle;
78
import android.view.Menu;
89
import android.view.MenuItem;
@@ -29,6 +30,7 @@ public class IDCardActivity extends RxVerIDActivity {
2930

3031
public static final String EXTRA_DETECTED_FACE = "com.appliedrec.verid.EXTRA_DETECTED_FACE";
3132
public static final String EXTRA_DOCUMENT_DATA = "com.appliedrec.verid.EXTRA_DOCUMENT_DATA";
33+
public static final String EXTRA_CARD_IMAGE_URI = "com.appliedrec.verid.EXTRA_CARD_IMAGE_URI";
3234
private static final int REQUEST_CODE_LIVE_FACE = 1;
3335
private DetectedFace cardFace;
3436
private DocumentData documentData;
@@ -40,11 +42,13 @@ protected void onCreate(Bundle savedInstanceState) {
4042
Intent intent = getIntent();
4143
if (intent != null) {
4244
cardFace = intent.getParcelableExtra(EXTRA_DETECTED_FACE);
43-
if (cardFace != null) {
45+
Uri cardImageUri = intent.getParcelableExtra(EXTRA_CARD_IMAGE_URI);
46+
if (cardImageUri != null) {
4447
ImageView imageView = findViewById(R.id.cardImageView);
48+
imageView.setOnClickListener(view -> showCardDetails());
4549
addDisposable(Single.create(emitter -> {
4650
try {
47-
Bitmap bitmap = BitmapFactory.decodeFile(cardFace.getImageUri().getPath());
51+
Bitmap bitmap = BitmapFactory.decodeFile(cardImageUri.getPath());
4852
RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
4953
drawable.setCornerRadius((float)bitmap.getHeight()/16f);
5054
emitter.onSuccess(drawable);
@@ -79,9 +83,7 @@ public boolean onPrepareOptionsMenu(Menu menu) {
7983
@Override
8084
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
8185
if (item.getItemId() == R.id.action_details) {
82-
Intent intent = new Intent(this, DocumentDetailsActivity.class);
83-
intent.putExtra(EXTRA_DOCUMENT_DATA, documentData);
84-
startActivity(intent);
86+
showCardDetails();
8587
return true;
8688
}
8789
return super.onOptionsItemSelected(item);
@@ -106,6 +108,12 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten
106108
}
107109
}
108110

111+
private void showCardDetails() {
112+
Intent intent = new Intent(this, DocumentDetailsActivity.class);
113+
intent.putExtra(EXTRA_DOCUMENT_DATA, documentData);
114+
startActivity(intent);
115+
}
116+
109117
private void startLivenessDetection() {
110118
addDisposable(getRxVerID().getVerID()
111119
.subscribeOn(Schedulers.io())

app/src/main/java/com/appliedrec/credentials/app/IntellicheckBarcodeVerifier.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ public Observable<Pair<String,String>> parseBarcode(String barcode) {
135135
String response = new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8);
136136
throw new Exception(response);
137137
}
138-
// TODO: Finish this
139138
JsonReader jsonReader = new JsonReader(new InputStreamReader(connection.getInputStream()));
140139
jsonReader.setLenient(true);
141140
jsonReader.beginObject();
@@ -144,7 +143,7 @@ public Observable<Pair<String,String>> parseBarcode(String barcode) {
144143
jsonReader.beginObject();
145144
while (jsonReader.hasNext()) {
146145
String name = jsonReader.nextName();
147-
if ("$".equals(name)) {
146+
if ("$".equals(name) || name == null || name.isEmpty()) {
148147
jsonReader.skipValue();
149148
} else if ("testCard".equals(name)) {
150149
emitter.onNext(new Pair<>(name, jsonReader.nextBoolean() ? "Yes" : "No"));

app/src/main/java/com/appliedrec/credentials/app/MainActivity.java

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import androidx.annotation.Nullable;
1313
import androidx.appcompat.app.AlertDialog;
1414
import androidx.constraintlayout.widget.Group;
15+
import androidx.core.util.Pair;
1516

1617
import com.appliedrec.uielements.RxVerIDActivity;
1718
import com.appliedrec.verid.core.Bearing;
@@ -101,9 +102,16 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
101102

102103
private void showCardFromResult(BlinkIdCombinedRecognizer.Result result) {
103104
byte[] frontImage = result.getEncodedFrontFullDocumentImage();
105+
byte[] faceImage = result.getEncodedFaceImage();
104106
documentData = new DocumentData(result);
105107
addDisposable(Single.create(single -> {
106108
try {
109+
if (frontImage.length == 0) {
110+
throw new Exception(getString(R.string.failed_to_collect_card_image));
111+
}
112+
if (faceImage.length == 0) {
113+
throw new Exception(getString(R.string.failed_to_detect_face_in_card));
114+
}
107115
File imageFile = new File(getFilesDir(), "cardFront.jpg");
108116
FileOutputStream outputStream = new FileOutputStream(imageFile);
109117
ByteArrayInputStream inputStream = new ByteArrayInputStream(frontImage);
@@ -114,18 +122,29 @@ private void showCardFromResult(BlinkIdCombinedRecognizer.Result result) {
114122
}
115123
outputStream.close();
116124
inputStream.close();
117-
single.onSuccess(Uri.fromFile(imageFile));
125+
Uri[] uris = new Uri[2];
126+
uris[0] = Uri.fromFile(imageFile);
127+
imageFile = File.createTempFile("verid_card_face_", ".jpg");
128+
outputStream = new FileOutputStream(imageFile);
129+
inputStream = new ByteArrayInputStream(faceImage);
130+
while ((read = inputStream.read(buffer, 0, buffer.length)) > 0) {
131+
outputStream.write(buffer, 0, read);
132+
}
133+
outputStream.close();
134+
inputStream.close();
135+
uris[1] = Uri.fromFile(imageFile);
136+
single.onSuccess(uris);
118137
} catch (Exception e) {
119-
single.onError(e);
138+
single.onError(new Exception(getString(R.string.failed_to_save_image_of_card), e));
120139
}
121-
}).cast(Uri.class)
122-
.flatMapObservable(imageUri -> getRxVerID().detectRecognizableFacesInImage(imageUri, 1).map(face -> new DetectedFace(face, Bearing.STRAIGHT, imageUri)))
140+
}).cast(Uri[].class)
141+
.flatMapObservable(imageUri -> getRxVerID().detectRecognizableFacesInImage(imageUri[1], 1).switchIfEmpty(getRxVerID().detectRecognizableFacesInImage(imageUri[0], 1)).map(face -> new Pair<>(new DetectedFace(face, Bearing.STRAIGHT, imageUri[1]), imageUri[0])))
123142
.singleOrError()
124143
.subscribeOn(Schedulers.io())
125144
.observeOn(AndroidSchedulers.mainThread())
126145
.subscribe(
127-
this::showCard,
128-
this::showError
146+
pair -> showCard(pair.first, pair.second),
147+
error -> showError(new Exception(getString(R.string.failed_to_detect_face_in_card), error))
129148
));
130149
}
131150

@@ -167,6 +186,8 @@ private void scanIDCard() {
167186
BlinkIdCombinedRecognizer recognizer = new BlinkIdCombinedRecognizer();
168187
recognizer.setReturnFullDocumentImage(true);
169188
recognizer.setEncodeFullDocumentImage(true);
189+
recognizer.setReturnFaceImage(true);
190+
recognizer.setEncodeFaceImage(true);
170191
recognizerBundle = new RecognizerBundle(recognizer);
171192
BlinkIdUISettings uiSettings = new BlinkIdUISettings(recognizerBundle);
172193
uiSettings.enableHighResSuccessFrameCapture(true);
@@ -176,18 +197,23 @@ private void scanIDCard() {
176197
private void showError(Throwable error) {
177198
progressBar.setVisibility(View.GONE);
178199
mainUIGroup.setVisibility(View.VISIBLE);
200+
String message = error.getLocalizedMessage();
201+
if (error.getCause() != null && error.getCause().getLocalizedMessage() != null && !error.getCause().getLocalizedMessage().isEmpty()) {
202+
message += ": "+error.getCause().getLocalizedMessage();
203+
}
179204
new AlertDialog.Builder(this)
180205
.setTitle(R.string.error)
181-
.setMessage(error.getLocalizedMessage())
206+
.setMessage(message)
182207
.setPositiveButton(android.R.string.ok, null)
183208
.create()
184209
.show();
185210
}
186211

187-
private void showCard(DetectedFace face) {
212+
private void showCard(DetectedFace face, Uri cardImageUri) {
188213
progressBar.setVisibility(View.GONE);
189214
mainUIGroup.setVisibility(View.VISIBLE);
190215
Intent intent = new Intent(this, IDCardActivity.class);
216+
intent.putExtra(IDCardActivity.EXTRA_CARD_IMAGE_URI, cardImageUri);
191217
intent.putExtra(IDCardActivity.EXTRA_DETECTED_FACE, face);
192218
if (documentData != null) {
193219
intent.putExtra(IDCardActivity.EXTRA_DOCUMENT_DATA, documentData);

app/src/main/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,7 @@
2828
<string name="proceed_anyway">Proceed anyway</string>
2929
<string name="selfie">Selfie</string>
3030
<string name="woman_holding_id_card">Woman holding ID card</string>
31+
<string name="failed_to_save_image_of_card">Failed to save an image of the ID card.</string>
32+
<string name="failed_to_detect_face_in_card">Failed to detect a face in the ID card.</string>
33+
<string name="failed_to_collect_card_image">Failed to collect image of the card.</string>
3134
</resources>

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ ext {
2323
veriduielementsVersion = '[1.0.0,2.0.0['
2424
versionMajor = 7
2525
versionMinor = 5
26-
versionPatch = 0
26+
versionPatch = 1
2727
versionClassifier = null
2828
versionClassifierVersion = ""
2929
minSdkVersion = 23

0 commit comments

Comments
 (0)