FingerprintImage.decode() returned null

Issue #1 invalid
Vijay Kanta created an issue

I am trying to implement this library in an Android project. Everything’s done as explained in the Java tutorial. However, when trying to do the moment of truth, matching two fingerprint images, I get this error.

Following is the error I am getting

Bitmap probeBm = BitmapFactory.decodeResource(getResources(), R.drawable.fingerprintblob);
Bitmap candidateBm = BitmapFactory.decodeResource(getResources(), R.drawable.fingerprintupload);

saveBitmapToFile(dir, "fingerprintblob.png", probeBm, Bitmap.CompressFormat.PNG, 100);
saveBitmapToFile(dir, "fingerprintupload.png", candidateBm, Bitmap.CompressFormat.PNG, 100);
byte[] probeImage = Files.readAllBytes(Paths.get(dir + File.separator + "fingerprintblob.png"));
byte[] candidateImage = Files.readAllBytes(Paths.get(dir + File.separator + "fingerprintupload.png"));

FingerprintTemplate candidate = new FingerprintTemplate(
        new FingerprintImage()
                .dpi(500)
                .decode(candidateImage)
);

FingerprintTemplate probe = new FingerprintTemplate(
        new FingerprintImage()
        .dpi(500)
        .decode(probeImage)
);

// now match
double score = new FingerprintMatcher()
        .index(probe)
        .match(candidate);

Log.d(TAG, "fingerprint match score " + score);

double threshold = 40;
boolean matches = score >= threshold;
Log.d(TAG, "fingerprint matches? " + matches);

And below is the error I am getting from stack trace print

2019-11-20 10:53:35.310 12137-12137/com.vizcreations.biometrics E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.vizcreations.biometrics, PID: 12137
    java.lang.BootstrapMethodError: Exception from call site #52 bootstrap method
        at com.machinezoo.sourceafis.ImageDecoder.decodeAny(ImageDecoder.java:79)
        at com.machinezoo.sourceafis.FingerprintImage.decode(FingerprintImage.java:84)
        at com.vizcreations.biometrics.DashboardActivity.testMatchLocalFingerprints(DashboardActivity.java:1087)
        at com.vizcreations.biometrics.DashboardActivity.captureFingerprint(DashboardActivity.java:607)
        at com.vizcreations.biometrics.DashboardActivity.onDialogOptionSelected(DashboardActivity.java:563)
        at com.vizcreations.biometrics.fragment.SearchstudentDialogFragment$2.onClick(SearchstudentDialogFragment.java:55)
        at androidx.appcompat.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1068)
        at android.widget.AdapterView.performItemClick(AdapterView.java:318)
        at android.widget.AbsListView.performItemClick(AbsListView.java:1198)
        at android.widget.AbsListView$PerformClick.run(AbsListView.java:3178)
        at android.widget.AbsListView$3.run(AbsListView.java:4132)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:201)
        at android.app.ActivityThread.main(ActivityThread.java:6810)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
     Caused by: java.lang.ClassCastException: Bootstrap method returned null
        at com.machinezoo.sourceafis.ImageDecoder.decodeAny(ImageDecoder.java:79) 
        at com.machinezoo.sourceafis.FingerprintImage.decode(FingerprintImage.java:84) 
        at com.vizcreations.biometrics.DashboardActivity.testMatchLocalFingerprints(DashboardActivity.java:1087) 
        at com.vizcreations.biometrics.DashboardActivity.captureFingerprint(DashboardActivity.java:607) 
        at com.vizcreations.biometrics.DashboardActivity.onDialogOptionSelected(DashboardActivity.java:563) 
        at com.vizcreations.biometrics.fragment.SearchstudentDialogFragment$2.onClick(SearchstudentDialogFragment.java:55) 
        at androidx.appcompat.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1068) 
        at android.widget.AdapterView.performItemClick(AdapterView.java:318) 
        at android.widget.AbsListView.performItemClick(AbsListView.java:1198) 
        at android.widget.AbsListView$PerformClick.run(AbsListView.java:3178) 
        at android.widget.AbsListView$3.run(AbsListView.java:4132) 
        at android.os.Handler.handleCallback(Handler.java:873) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:201) 
        at android.app.ActivityThread.main(ActivityThread.java:6810)

Seemed like I sent an empty image, but the byte count was greater than 0, so it’s not a null image. Only thing I can think of is that it may not be encoded with 500 dpi? I had originally converted the fingerprint to PNG image and save as BLOB to a MySQL database, then retrieve it back as image and downloaded it. The fingerprint I am matching with it is from a scanner again dumped as image before being converted to file and uploaded to a Node JS server from a byte[] array the scanner had outputted.

Comments (9)

  1. Vijay Kanta reporter

    When placed inside a nested try/catch block, the following is the output.

    Caused by: java.lang.NoClassDefFoundError: Invalid descriptor: MAX_CACHED_BITMAP_SIZE.
            at com.machinezoo.sourceafis.ImageDecoder.decodeAny(ImageDecoder.java:79) 
            at com.machinezoo.sourceafis.FingerprintImage.decode(FingerprintImage.java:84) 
            at com.vizcreations.biometrics.DashboardActivity.testMatchLocalFingerprints(DashboardActivity.java:1088) 
            at com.vizcreations.biometrics.DashboardActivity.captureFingerprint(DashboardActivity.java:607) 
            at com.vizcreations.biometrics.DashboardActivity.onDialogOptionSelected(DashboardActivity.java:563) 
            at com.vizcreations.biometrics.fragment.SearchstudentDialogFragment$2.onClick(SearchstudentDialogFragment.java:55) 
            at androidx.appcompat.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1068) 
            at android.widget.AdapterView.performItemClick(AdapterView.java:318) 
            at android.widget.AbsListView.performItemClick(AbsListView.java:1158) 
            at android.widget.AbsListView$PerformClick.run(AbsListView.java:3127) 
            at android.widget.AbsListView$3.run(AbsListView.java:4042) 
            at android.os.Handler.handleCallback(Handler.java:790) 
            at android.os.Handler.dispatchMessage(Handler.java:99) 
            at android.os.Looper.loop(Looper.java:164) 
            at android.app.ActivityThread.main(ActivityThread.java:6494) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
    

  2. Robert Važan repo owner

    Try the configuration below. Note the compileOptions block and buildToolsVersion.

    android {
        compileSdkVersion 29
        buildToolsVersion "29.0.2"
        defaultConfig {
            applicationId "com.machinezoo.sourceafis.android.test"
            minSdkVersion 24
            targetSdkVersion 29
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    }
    

    Does it help?

  3. Vijay Kanta reporter

    The version compatibility gradle code to Java 8.0 and few of my tweaks to make image pure PNG has fixed this problem.

    Some adjustments to my code are

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    probeBm.compress(Bitmap.CompressFormat.PNG, 100, stream);
    
    byte[] probeImage = stream.toByteArray();
    
    .. same with candidateImage before passing onto fingerprinttemplate
    

    These have to be put because the Android IntelliSense was telling me Files.readAllBytes() and Paths.get() need to have minimum SDK 26, and I am running minimum SDK 24 now

  4. Robert Važan repo owner

    I am happy the problem is fixed now. BTW, you don’t have to save anything to a file if you already have the image in memory. It is also unnecessary to decode it into Bitmap, because SourceAFIS already does that internally. All you have to do is to load the resource as byte[] and pass it to SourceAFIS.

  5. Log in to comment