.net, Clean Code, Security

Using C# to create a bitmap of a fingerprint from the BioMini scanner and Neurotec FFV SDK

Previously, I wrote about my experiences with the BioMini fingerprint scanner from Suprema and using it with the Neurotechnology Free Fingerprint Verification SDK. The last thing I mentioned in that post was that I’d research how to use these tools to scan a fingerprint and use .NET to generate a bitmap image of the finger that was scanned.

There is obviously a C# sample application bundled with the Neurotechnology FFV SDK – this is a Windows Forms application, and has quite a lot of functionality built around Enrollment (the act of scanning a fingerprint), Verification (the act of comparing a fingerprint to another), and storing fingerprints in a local database.

At this point, I am really just interested in scanning the fingerprint, and generating a bitmap of the scanned image. I wanted to cut through all of the extra sample applications code, and write the absolute bare minimum code necessary to do this. I also wanted to make this code clean – potentially with a view to creating a Nuget package.

First I designed what the interface needed to look like – I wanted to enroll a fingerprint, and create a bitmap file. Also, I wanted to make sure that the resources used by the library were released, so I knew I needed to implement the IDisposable interface. I designed my interface to look like the code below.

public interface IFingerprintScanner : IDisposable
{
    void CreateBitmapFile(string path);
        
    void Enroll();
}

Next I needed an implementation of enrolling a fingerprint and generating the bitmap image.

Enrollment and image generation is pretty straightforward – the Neurotechnology FFV documentation is extremely useful for this. There are three steps:

  • First create a scanning engine, based on the Nffv object in the FFV SDK. This object takes three parameters – the verification database name and password (which  I don’t care about, I just want to enroll), and a string representing the manufacturer code (for the BioMini scanner, the manufacturer code is “Suprema”);
_scanningEngine = new Nffv("FakeDatabaseName", "", _manufacturerCode);
  • Then call the Enroll method, which makes the scanner hardware switch on and wait for someone to put their finger on the screen. This returns an NffvUser object, which contains the information scanned in.
_scannerUser = _scanningEngine.Enroll(_timeout, out engineStatus);
  • Finally, I can then call the GetBitmap() method on the NffvUser object, which returns a Bitmap object.
var image = _scannerUser.GetBitmap();

I decided to create a scanner class that was abstract, which would take the manufacturer code as a parameter – the class looks like the code below:

public abstract class AbstractFingerprintScanner : IDisposable, IFingerprintScanner
{
    private Nffv _scanningEngine;
        
    private NffvStatus engineStatus;

    private NffvUser _scannerUser;

    private uint _timeout;

    private string _manufacturerCode;

    public AbstractFingerprintScanner(uint timeout, string manufacturerCode)
    {
        _timeout = timeout;
        _manufacturerCode = manufacturerCode;
    }

    public void Enroll()
    {
        _scanningEngine = new Nffv("FakeDatabaseName", "", _manufacturerCode);
            
        // when this next line is executed, a signal is sent to the hardware fingerprint scanner to start detecting a fingerprint.
        _scannerUser = _scanningEngine.Enroll(_timeout, out engineStatus);
    }

    public void CreateBitmapFile(string path)
    {
        if (engineStatus == NffvStatus.TemplateCreated)
        {
            var image = _scannerUser.GetBitmap();
            image.Save(path);
        }
        else
        {
            throw new Exception(string.Format("Bitmap was not created - Enrollment result status: {0}", engineStatus));
        }
    }

    public void Dispose()
    {
        _scanningEngine.Dispose();

        if (_scanningEngine != null)
        {
            _scanningEngine = null;
        }
    }
}

This means that I can create a very simple concrete instantiation of the BioMini fingerprint scanner software:

public class BioMiniFingerprintScanner : AbstractFingerprintScanner
{
    private static string SCANNER_MANUFACTURER = "Suprema";

    public BioMiniFingerprintScanner(uint timeout) : base(timeout, SCANNER_MANUFACTURER) { }
}

And finally, the code I need to enroll and create a print becomes simple also:

static void Main(string[] args)
{
    uint timeout = 10000;

    using (var scanner = new BioMiniFingerprintScanner(timeout))
    {
        scanner.Enroll();
        scanner.CreateBitmapFile(@"C:\Users\jeremy\Desktop\myFingerprint.bmp");
    }
}