Skip to content

Commit

Permalink
Merge pull request #166 from BlinkID/release/v6.6.0
Browse files Browse the repository at this point in the history
Release/v6.6.0
  • Loading branch information
mparadina authored May 13, 2024
2 parents a5e583c + 62b7796 commit 8b47866
Show file tree
Hide file tree
Showing 27 changed files with 1,177 additions and 527 deletions.
2 changes: 1 addition & 1 deletion BlinkID/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "blinkid-cordova",
"version": "6.5.0",
"version": "6.7.0",
"description": "A small and powerful ID card scanning library",
"cordova": {
"id": "blinkid-cordova",
Expand Down
3 changes: 1 addition & 2 deletions BlinkID/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="blinkid-cordova"
version="6.5.0">
version="6.7.0">

<name>BlinkIdScanner</name>
<description>A small and powerful ID card scanning library</description>
Expand Down Expand Up @@ -154,7 +154,6 @@
<framework src="OpenGLES.framework" />
<framework src="Accelerate.framework" />
<framework src="src/ios/BlinkID.xcframework" custom="true" embed="true"/>

<preference name="CAMERA_USAGE_DESCRIPTION" default=" " />
<config-file target="*-Info.plist" parent="NSCameraUsageDescription">
<string>$CAMERA_USAGE_DESCRIPTION</string>
Expand Down
2 changes: 1 addition & 1 deletion BlinkID/scripts/initIOSFramework.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
HERE="$(dirname "$(test -L "$0" && readlink "$0" || echo "$0")")"
pushd "${HERE}/../src/ios/" > /dev/null

LINK='https://github.com/BlinkID/blinkid-ios/releases/download/v6.5.0/BlinkID.xcframework.zip'
LINK='https://github.com/BlinkID/blinkid-ios/releases/download/v6.7.1/BlinkID.xcframework.zip'
FILENAME='BlinkID.xcframework.zip'

# BlinkID framework will be obtained via wget or curl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,25 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.NonNull;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;

import com.microblink.blinkid.MicroblinkSDK;
import com.microblink.blinkid.entities.recognizers.RecognizerBundle;
import com.microblink.blinkid.intent.IntentDataTransferMode;
import com.microblink.blinkid.uisettings.UISettings;
import com.microblink.blinkid.plugins.cordova.overlays.OverlaySettingsSerializers;
import com.microblink.blinkid.plugins.cordova.recognizers.RecognizerSerializers;
import com.microblink.blinkid.locale.LanguageUtils;
import com.microblink.blinkid.directApi.DirectApiErrorListener;
import com.microblink.blinkid.directApi.RecognizerRunner;
import com.microblink.blinkid.hardware.orientation.Orientation;
import com.microblink.blinkid.metadata.recognition.FirstSideRecognitionCallback;
import com.microblink.blinkid.recognition.RecognitionSuccessType;
import com.microblink.blinkid.metadata.MetadataCallbacks;
import com.microblink.blinkid.view.recognition.ScanResultListener;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
Expand All @@ -29,11 +41,13 @@ public class BlinkIDScanner extends CordovaPlugin {
private static final int REQUEST_CODE = 1337;

private static final String SCAN_WITH_CAMERA = "scanWithCamera";
private static final String SCAN_WITH_DIRECT_API = "scanWithDirectApi";
private static final String CANCELLED = "cancelled";

private static final String RESULT_LIST = "resultList";

private RecognizerBundle mRecognizerBundle;
private RecognizerRunner mRecognizerRunner;
private boolean mFirstSideScanned = false;
private CallbackContext mCallbackContext;

/**
Expand Down Expand Up @@ -69,18 +83,11 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo

try {
if (action.equals(SCAN_WITH_CAMERA)) {
JSONObject jsonOverlaySettings = args.getJSONObject(0);
JSONObject jsonRecognizerCollection = args.getJSONObject(1);
JSONObject jsonLicenses = args.getJSONObject(2);

setLicense(jsonLicenses);
mRecognizerBundle = RecognizerSerializers.INSTANCE.deserializeRecognizerCollection(jsonRecognizerCollection);
UISettings overlaySettings = OverlaySettingsSerializers.INSTANCE.getOverlaySettings(this.cordova.getContext(), jsonOverlaySettings, mRecognizerBundle);

// unable to use ActivityRunner because we need to use cordova's activity launcher
Intent intent = new Intent(this.cordova.getContext(), overlaySettings.getTargetActivity());
overlaySettings.saveToIntent(intent);
this.cordova.startActivityForResult(this, intent, REQUEST_CODE);
//Scan with camera
scanWithCamera(args);
} else if (action.equals(SCAN_WITH_DIRECT_API)) {
//Scan with DirectAPI
scanWithDirectApi(args);
} else {
return false;
}
Expand All @@ -91,6 +98,157 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo
}
}

private void scanWithCamera(JSONArray arguments) throws JSONException{
try {
JSONObject jsonOverlaySettings = arguments.getJSONObject(0);
JSONObject jsonRecognizerCollection = arguments.getJSONObject(1);
JSONObject jsonLicenses = arguments.getJSONObject(2);

setLicense(jsonLicenses);
setLanguage(jsonOverlaySettings.getString("language"),
jsonOverlaySettings.getString("country"));
mRecognizerBundle = RecognizerSerializers.INSTANCE.deserializeRecognizerCollection(jsonRecognizerCollection);
UISettings overlaySettings = OverlaySettingsSerializers.INSTANCE.getOverlaySettings(this.cordova.getContext(), jsonOverlaySettings, mRecognizerBundle);

// unable to use ActivityRunner because we need to use cordova's activity launcher
Intent intent = new Intent(this.cordova.getContext(), overlaySettings.getTargetActivity());
overlaySettings.saveToIntent(intent);
this.cordova.startActivityForResult(this, intent, REQUEST_CODE);
} catch (JSONException e) {
mCallbackContext.error("Could not start scanWithCamera.\nJSON error: " + e);
}
}

private void scanWithDirectApi(JSONArray arguments) throws JSONException {
//DirectAPI processing
JSONObject jsonRecognizerCollection = arguments.getJSONObject(0);
JSONObject jsonLicense = arguments.getJSONObject(3);
setLicense(jsonLicense);

ScanResultListener mScanResultListenerBackSide = new ScanResultListener() {
@Override
public void onScanningDone(@NonNull RecognitionSuccessType recognitionSuccessType) {
mFirstSideScanned = false;
handleDirectApiResult(recognitionSuccessType);
}
@Override
public void onUnrecoverableError(@NonNull Throwable throwable) {
handleDirectApiError(throwable.getMessage());
}
};

FirstSideRecognitionCallback mFirstSideRecognitionCallback = new FirstSideRecognitionCallback() {
@Override
public void onFirstSideRecognitionFinished() {
mFirstSideScanned = true;
}
};

ScanResultListener mScanResultListenerFrontSide = new ScanResultListener() {
@Override
public void onScanningDone(@NonNull RecognitionSuccessType recognitionSuccessType) {
if (mFirstSideScanned) {
//multiside recognizer used
try {
if (!arguments.getString(2).isEmpty() && !arguments.isNull(2)) {
processImage(arguments.getString(2), mScanResultListenerBackSide);
} else if (recognitionSuccessType != RecognitionSuccessType.UNSUCCESSFUL) {
handleDirectApiResult(recognitionSuccessType);
} else {
handleDirectApiError("Could not extract the information from the front side and the back side is empty!");
}
} catch (JSONException e) {
throw new RuntimeException(e);
}
} else if (!mFirstSideScanned && recognitionSuccessType != RecognitionSuccessType.UNSUCCESSFUL){
//singleside recognizer used
handleDirectApiResult(recognitionSuccessType);
} else {
mFirstSideScanned = false;
handleDirectApiError("Could not extract the information with DirectAPI!");
}
}
@Override
public void onUnrecoverableError(@NonNull Throwable throwable) {
handleDirectApiError(throwable.getMessage());
}
};

setupRecognizerRunner(jsonRecognizerCollection, mFirstSideRecognitionCallback);

if (!arguments.getString(1).isEmpty() && !arguments.isNull(1)) {
processImage(arguments.getString(1), mScanResultListenerFrontSide);
} else {
handleDirectApiError("The provided image for the 'frontImage' parameter is empty!");
}
}

private void setupRecognizerRunner(JSONObject jsonRecognizerCollection, FirstSideRecognitionCallback mFirstSideRecognitionCallback) {
if (mRecognizerRunner != null) {
mRecognizerRunner.terminate();
}

mRecognizerBundle = RecognizerSerializers.INSTANCE.deserializeRecognizerCollection(jsonRecognizerCollection);

try {
mRecognizerRunner = RecognizerRunner.getSingletonInstance();
} catch (Exception e) {
handleDirectApiError("DirectAPI not supported: " + e.getMessage());
}

MetadataCallbacks metadataCallbacks = new MetadataCallbacks();
metadataCallbacks.setFirstSideRecognitionCallback(mFirstSideRecognitionCallback);
mRecognizerRunner.setMetadataCallbacks(metadataCallbacks);
mRecognizerRunner.initialize(cordova.getContext(), mRecognizerBundle, new DirectApiErrorListener() {
@Override
public void onRecognizerError(@NonNull Throwable throwable) {
handleDirectApiError("Failed to initialize recognizer with DirectAPI: " + throwable.getMessage());
}
});
}

private void processImage(String base64Image, ScanResultListener scanResultListener) {
Bitmap image = base64ToBitmap(base64Image);
if (image != null) {
mRecognizerRunner.recognizeBitmap(
base64ToBitmap(base64Image),
Orientation.ORIENTATION_LANDSCAPE_RIGHT,
scanResultListener
);
} else {
handleDirectApiError("Could not decode the Base64 image!");
}
}

private void handleDirectApiResult(RecognitionSuccessType recognitionSuccessType) {
if (recognitionSuccessType != RecognitionSuccessType.UNSUCCESSFUL) {
JSONObject result = new JSONObject();
try {
result.put(CANCELLED, false);
} catch (JSONException e) {
throw new RuntimeException(e);
}
try {
JSONArray resultList = RecognizerSerializers.INSTANCE.serializeRecognizerResults(mRecognizerBundle.getRecognizers());
result.put(RESULT_LIST, resultList);
} catch(JSONException e) {
throw new RuntimeException(e);
}
mCallbackContext.success(result);

} else {
handleDirectApiError("Could not extract the information with DirectAPI!");
}
}

private void handleDirectApiError(String errorMessage) {
mCallbackContext.error(errorMessage);
mFirstSideScanned = false;
if (mRecognizerRunner != null) {
mRecognizerRunner.resetRecognitionState(true);
}
}

private void setLicense( JSONObject jsonLicense ) throws JSONException {
MicroblinkSDK.setShowTrialLicenseWarning(
jsonLicense.optBoolean("showTrialLicenseKeyWarning", true)
Expand All @@ -106,6 +264,15 @@ private void setLicense( JSONObject jsonLicense ) throws JSONException {
MicroblinkSDK.setIntentDataTransferMode(IntentDataTransferMode.PERSISTED_OPTIMISED);
}

private Bitmap base64ToBitmap(String base64String) {
byte[] decodedBytes = Base64.decode(base64String, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
}

private void setLanguage(String language, String country) {
LanguageUtils.setLanguageAndCountry(language, country, this.cordova.getContext());
}

/**
* Called when the scanner intent completes.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ public UISettings createUISettings(Context context, JSONObject jsonUISettings, R

boolean showIntroductionDialog = jsonUISettings.optBoolean("showIntroductionDialog", false);
settings.setShowIntroductionDialog(showIntroductionDialog);

boolean showTorchButton = jsonUISettings.optBoolean("showTorchButton", true);
settings.setShowTorchButton(showTorchButton);

boolean showCancelButton = jsonUISettings.optBoolean("showCancelButton", true);
settings.setShowCancelButton(showCancelButton);

long onboardingButtonTooltipDelay = jsonUISettings.optLong("onboardingButtonTooltipDelay", 12000);
settings.setShowTooltipTimeIntervalMs(onboardingButtonTooltipDelay);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.microblink.blinkid.entities.recognizers.blinkid.generic.AlphabetType;
import com.microblink.blinkid.entities.recognizers.blinkid.generic.Side;
import com.microblink.blinkid.entities.recognizers.blinkid.generic.imageanalysis.CardRotation;
import com.microblink.blinkid.entities.recognizers.blinkid.generic.DocumentNumberAnonymizationSettings;

import org.json.JSONArray;
import org.json.JSONException;
Expand Down Expand Up @@ -124,6 +125,7 @@ public static JSONObject serializeImageAnalysisResult(ImageAnalysisResult imageA
jsonImageAnalysis.put("barcodeDetectionStatus", SerializationUtils.serializeEnum(imageAnalysisResult.getBarcodeDetectionStatus()));
jsonImageAnalysis.put("cardRotation", BlinkIDSerializationUtils.serializeCardRotation(imageAnalysisResult.getCardRotation()));
jsonImageAnalysis.put("cardOrientation", SerializationUtils.serializeEnum(imageAnalysisResult.getCardOrientation()));
jsonImageAnalysis.put("realIdDetectionStatus", SerializationUtils.serializeEnum(imageAnalysisResult.getRealIdDetectionStatus()));
return jsonImageAnalysis;
}

Expand Down Expand Up @@ -331,6 +333,7 @@ public static ClassAnonymizationSettings[] deserializeClassAnonymizationSettings
Country country = Country.NONE;
Region region = Region.NONE;
Type type = Type.NONE;
DocumentNumberAnonymizationSettings documentNumberAnonymizationSettings = null;
try {
JSONObject jsonClassAnonymizationSettings = jsonArray.getJSONObject(i);

Expand All @@ -354,7 +357,13 @@ public static ClassAnonymizationSettings[] deserializeClassAnonymizationSettings
} catch ( JSONException e) {
type = null;
}
ClassAnonymizationSettings classAnonymizationSettings = new ClassAnonymizationSettings(country, region, type, fieldTypes);
try {
JSONObject jsonDocumentNumberAnonymizationSettings = jsonClassAnonymizationSettings.getJSONObject("documentNumberAnonymizationSettings");
documentNumberAnonymizationSettings = deserializeDocumentNumberAnonymizationSettings(jsonDocumentNumberAnonymizationSettings);
} catch (JSONException exception) {
documentNumberAnonymizationSettings = null;
}
ClassAnonymizationSettings classAnonymizationSettings = new ClassAnonymizationSettings(country, region, type, fieldTypes, documentNumberAnonymizationSettings);
classAnonymizationSettingsArray[i] = classAnonymizationSettings;
} catch (JSONException e) {
throw new RuntimeException(e);
Expand All @@ -365,4 +374,11 @@ public static ClassAnonymizationSettings[] deserializeClassAnonymizationSettings
return new ClassAnonymizationSettings[]{};
}
}
private static DocumentNumberAnonymizationSettings deserializeDocumentNumberAnonymizationSettings (JSONObject jsonDocumentNumberAnonymizationSettings) {
try {
return new DocumentNumberAnonymizationSettings(jsonDocumentNumberAnonymizationSettings.getInt("prefixDigitsVisible"),jsonDocumentNumberAnonymizationSettings.getInt("suffixDigitsVisible"));
} catch (JSONException exception){
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public JSONObject serializeResult(Recognizer<?> recognizer) {
jsonResult.put("backVizResult", BlinkIDSerializationUtils.serializeVizResult(result.getBackVizResult()));
jsonResult.put("barcodeCameraFrame", SerializationUtils.encodeImageBase64(result.getBarcodeCameraFrame()));
jsonResult.put("barcodeResult", BlinkIDSerializationUtils.serializeBarcodeResult(result.getBarcodeResult()));
jsonResult.put("bloodType", BlinkIDSerializationUtils.serializeStringResult(result.getBloodType()));
jsonResult.put("classInfo", BlinkIDSerializationUtils.serializeClassInfo(result.getClassInfo()));
jsonResult.put("dataMatch", BlinkIDSerializationUtils.serializeDataMatchResult(result.getDataMatch()));
jsonResult.put("dateOfBirth", BlinkIDSerializationUtils.serializeDateResult(result.getDateOfBirth()));
Expand Down Expand Up @@ -96,6 +97,7 @@ public JSONObject serializeResult(Recognizer<?> recognizer) {
jsonResult.put("scanningFirstSideDone", result.isScanningFirstSideDone());
jsonResult.put("sex", BlinkIDSerializationUtils.serializeStringResult(result.getSex()));
jsonResult.put("signatureImage", SerializationUtils.encodeImageBase64(result.getSignatureImage()));
jsonResult.put("sponsor", BlinkIDSerializationUtils.serializeStringResult(result.getSponsor()));
} catch (JSONException e) {
// see https://developer.android.com/reference/org/json/JSONException
throw new RuntimeException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public JSONObject serializeResult(Recognizer<?> recognizer) {
jsonResult.put("age", result.getAge());
jsonResult.put("barcodeCameraFrame", SerializationUtils.encodeImageBase64(result.getBarcodeCameraFrame()));
jsonResult.put("barcodeResult", BlinkIDSerializationUtils.serializeBarcodeResult(result.getBarcodeResult()));
jsonResult.put("bloodType", BlinkIDSerializationUtils.serializeStringResult(result.getBloodType()));
jsonResult.put("cameraFrame", SerializationUtils.encodeImageBase64(result.getCameraFrame()));
jsonResult.put("classInfo", BlinkIDSerializationUtils.serializeClassInfo(result.getClassInfo()));
jsonResult.put("dateOfBirth", BlinkIDSerializationUtils.serializeDateResult(result.getDateOfBirth()));
Expand Down Expand Up @@ -83,6 +84,7 @@ public JSONObject serializeResult(Recognizer<?> recognizer) {
jsonResult.put("residentialStatus", BlinkIDSerializationUtils.serializeStringResult(result.getResidentialStatus()));
jsonResult.put("sex", BlinkIDSerializationUtils.serializeStringResult(result.getSex()));
jsonResult.put("signatureImage", SerializationUtils.encodeImageBase64(result.getSignatureImage()));
jsonResult.put("sponsor", BlinkIDSerializationUtils.serializeStringResult(result.getSponsor()));
jsonResult.put("vizResult", BlinkIDSerializationUtils.serializeVizResult(result.getVizResult()));
} catch (JSONException e) {
// see https://developer.android.com/reference/org/json/JSONException
Expand Down
2 changes: 1 addition & 1 deletion BlinkID/src/android/libBlinkID.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ repositories {
}

dependencies {
implementation('com.microblink:blinkid:6.5.0@aar') {
implementation('com.microblink:blinkid:6.7.0@aar') {
transitive = true
}
}
Expand Down
Loading

0 comments on commit 8b47866

Please sign in to comment.