GithubHelp home page GithubHelp logo

jnbis's Introduction

JNBIS

Java Implementation of NIST Biometric Image Software (NBIS)

CI Maven Central GitHub license

🛠️ NOTE: Due to lack of time, this project is in maintenance mode. Only critical bugs will be fixed. Pull requests are always welcome!

About JNBIS

JNBIS is a library, written in Java, to extract and decode NIST (National Institute of Standards and Technology) compressed files and WSQ (Wavelet Scalar Quantization) images. The code has been converted from NBIS (NIST Biometric Image Software) version 1.1 which is written in C. You can find more about NIST Biometric Image Software here.

Quick Start

Build and Install

JNBIS is available in the maven central repository, so you just need to download and add it to your project libraries or if you are using maven, add it to project dependencies. Maven Central

<dependency>
  <groupId>com.github.mhshams</groupId>
  <artifactId>jnbis</artifactId>
  <version>2.x.x</version>
</dependency>

Alternatively, you can clone the source code and build it with maven. You need JDK version 1.8 or higher to build the code.

$ git clone [email protected]:mhshams/jnbis.git
$ cd jnbis
$ mvn package

Examples

WSQ Decoding

Convert WSQ image to PNG image and return the result as File

File png = Jnbis.wsq()
                .decode("path/to/wsq/file.wsq")
                .toPng()
                .asFile("/path/to/final/file.png");

Convert WSQ image to GIF image and return the result as File

File gif = Jnbis.wsq()
               .decode(new File("path/to/wsq/file.wsq"))
               .toGif()
               .asFile("/path/to/final/file.gif");

Convert WSQ image (as input stream) to JPEG image and return the result as File

File jpg = Jnbis.wsq()
                .decode(wsqInputStream)
                .toJpg()
                .asFile("/path/to/final/file.jpg");

Convert WSQ image to PNG image and return the result as InputStream

 InputStream pngStream = Jnbis.wsq()
                              .decode("path/to/wsq/file.wsq")
                              .toPng()
                              .asInputStream();

Convert WSQ image to GIF image and return the result as Byte Array

byte[] gifBytes = Jnbis.wsq()
                       .decode(new File("path/to/wsq/file.wsq"))
                       .toGif()
                       .asByteArray();

For more examples check the SampleWsqTest.java in the project source.

NIST Decoding

Decode a NIST file with given file name

Nist nist = Jnbis.nist().decode("/path/to/nist/file"));

Decode a NIST file with given File instance

Nist nist = Jnbis.nist().decode(new File("/path/to/nist/file"));

Decode a NIST file with given InputStream instance

Nist nist = Jnbis.nist().decode(nistInputStream));

Nist instance contains different types of data, depending on file type. Here is a sample code that extract all fingerprints and save them in individual files.

Nist nist = Jnbis.nist().decode(new File("/path/to/nist/file"));

for (HighResolutionGrayscaleFingerprint fp : nist.getHiResGrayscaleFingerprints()) {
    Jnbis.wsq()
        .decode(fp.getImageData())
        .toPng()
        .asFile("/path/fp-" + fp.getImageDesignationCharacter() + ".png");
}

For more examples check the SampleNistTest.java and AnsiReferencesTest.java in the project source.

jnbis's People

Contributors

mhshams avatar oculushut avatar tgabi333 avatar ychawla avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jnbis's Issues

Add module-info.java

Please add module-info.java. It will ease use of the library in dependent libraries and applications that are using Java 9 modules. In order to do this, you either have to upgrade to Java 9+ or create multi-release JAR. Given how old Java 8 is, I would recommend upgrading to Java 9 or even Java 11. It's much simpler than building multi-release JARs. Java 8 libs and apps can keep using older versions of the library.

HighResolutionGrayscaleFingerprint Image metadata is null

I am trying to get image metadata for a HighResolutionGrayscaleFingerprint such as:

CompressionAlgorithm
VerticalLineLength
HorizontalLineLength

However, in the NIST file samples/nist/sample.an2, all of this data is null. Is this metadata not available for this particular sample instance?

Parse error with some WSQ files

I have some WSQs created from paper scans which cause a parse error:

java.lang.RuntimeException: ERROR : getc_marker_wsq : No SOB, Table, or comment markers : 65441
at org.jnbis.internal.WsqDecoder.getCMarkerWSQ(WsqDecoder.java:107) ~[jnbis-2.0.0.jar!/:na]
at org.jnbis.internal.WsqDecoder.huffmanDecodeDataMem(WsqDecoder.java:730) ~[jnbis-2.0.0.jar!/:na]
at org.jnbis.internal.WsqDecoder.decode(WsqDecoder.java:39) ~[jnbis-2.0.0.jar!/:na]

It looks like the end-of-input marker WsqHelper.EOI_WSQ is unexpected here.

Not sure if this is a correct solution, but the attached patch helped in my particular case.

wsqdecoder.zip

Adding Android Support

The Issue:

The WSQ conversion does not work on Android since it uses the java.awt.* library which is not implemented in the Android SDK. As a result, you must use the android.graphics.* library. The only method that needed to be redone was the BitmapHandler.convert() method since it was the only one that used the awt library.

The Solution:

Note: I changed the name of the jnbis.Bitmap class to be MyImageBitmap to avoid name space conflicts with android.graphics.Bitmap.

Here is my implementation of the BitmapHandler.convert() method:

/**
 * Converts the given <code>MyImageBitmap</code> to the specified image format and returns it as byte array.
 *
 * @param myImageBitmap the given bitmap, not null
 * @param format the given target image format, not null
 * @return the converted data in byte array format, not null
 */
private byte[] convert(MyImageBitmap myImageBitmap, String format) {
    int width = myImageBitmap.getWidth();
    int height = myImageBitmap.getHeight();

    byte[] imgRGB888 = myImageBitmap.getPixels();

    Bitmap bmp2 = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

    int[] colors = new int[width * height];

    //We need to convert the image from a byte array to a
    // int color array so we can create the Android Bitmap
    int r,g,b;
    for (int ci = 0; ci < colors.length; ci++) {
        r = (int)(0x000000ff & imgRGB888[ci]);
        g = (int)(0x000000ff & imgRGB888[ci]);
        b = (int)(0x000000ff & imgRGB888[ci]);
        colors[ci] = Color.rgb(r, g, b);
    }

    bmp2.setPixels(colors, 0, width, 0, 0, width, height);

    Bitmap.CompressFormat compressFormat;

    if (format.equals("jpeg")){
        compressFormat = android.graphics.Bitmap.CompressFormat.JPEG;
    }else{//must be png
        compressFormat = android.graphics.Bitmap.CompressFormat.PNG;
    }

    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){
        bmp2.compress(compressFormat, 100, outputStream);
        return outputStream.toByteArray();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

You will also need to remove the java.awt.* imports at the top of the class for this to compile.

This solution allowed me to convert WSQ images to JPEG byte arrays and display them in an ImageView no problem.

This is basically how I am using it:

byte[] wsqImageBytes = //get wsq image bytes from somewhere
byte[] convertedImageBytes = Jnbis.wsq().decode(wsqImageBytes).toJpg().asByteArray();
int len = convertedImageBytes.length;
Bitmap bmp = BitmapFactory.decodeByteArray(convertedImageBytes, 0, len, null);
imageView.setImageBitmap(bmp);

Moving Forward:

  • We might want to consider creating a fork of the project for Android.
  • [Optional] The tests will need to be re-written to work in an Android environment.

Extra Notes for Using This Library in Android:

  • I cloned the repo and added it as a module in my Android project and made the changes in the module.
  • I removed the tests since as they are written, they don't work in Android environment.

Issue with image decoding

When decoding some of the NIST files it crashes with exception as such:

java.lang.RuntimeException: ERROR : getCMarkerWSQ : No SOI marker : 0
	at org.jnbis.internal.WsqDecoder.getCMarkerWSQ(WsqDecoder.java:85)
	at org.jnbis.internal.WsqDecoder.decode(WsqDecoder.java:19)
	at org.jnbis.api.handler.WsqHandler.decode(WsqHandler.java:71)
	...

Flow is something along the lines of this:

for (VariableResolutionLatentImage fingerprintImage : nist.getVariableResLatentImages()) {
      var xyz = Jnbis.wsq()
           .decode(fingerprintImage.getImageData())  // Throws an exception
           .toJpg()
           .asByteArray();
}

This viewer seems to be able to parse them just fine, not sure if it helps but it says Record Type 13 next to the image

Tested with versions 2.1.2 and 1.2.1

A proper builder for Nist model.

I would like to have Nist class immutable. all setter method must be moved to a builder class which is internal to NistDecoder.

how to convert file between wsq and png format

sir ,
I am a newbie.
Please find attached the log after running
mvn package
31-mvn-package-in-jnbis.txt

My aim is to convert wsq file to png and vice versa.
i saw https://github.com/kareez/jnbis/blob/develop/README.md

Still , am unable to figure out . How to use the lines below ?

File png = Jnbis.wsq()
.decode("path/to/wsq/file.wsq")
.toPng()
.asFile("/path/to/final/file.png");

All I understand is that I will put absolute file path for input and output in above.
But how to run the above command ?

Thanks.

Add metadata to signature

Thanks for a great project, I've been using it for a few months now. Below is a simple patch I needed for gathering metadata about the signature image. Hope you can use it.

Index: src/main/java/org/jnbis/api/model/record/SignatureImage.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8

diff --git a/src/main/java/org/jnbis/api/model/record/SignatureImage.java b/src/main/java/org/jnbis/api/model/record/SignatureImage.java
--- a/src/main/java/org/jnbis/api/model/record/SignatureImage.java (revision f5f2178)
+++ b/src/main/java/org/jnbis/api/model/record/SignatureImage.java (revision fdef3ce413c46d149a0e2c32e38f04ed233a44ff)
@@ -7,4 +7,29 @@
*/
public class SignatureImage extends BaseImageRecord {

  • private String signatureType, signatureRepresentationType, imageScanningResolution;

  • public void setSignatureType(String value) {

  •    this.signatureType = value;
    
  • }

  • public String getSignatureType() {

  •    return signatureType;
    
  • }

  • public void setSignatureRepresentationType(String value) {

  •    this.signatureRepresentationType = value;
    
  • }

  • public String getSignatureRepresentationType() {

  •    return signatureRepresentationType;
    
  • }

  • public void setImageScanningResolution(String valueOf) {

  •    this.imageScanningResolution = imageScanningResolution;
    
  • }

  • public String getImageScanningResolution() {

  •    return imageScanningResolution;
    
  • }
    }
    Index: src/main/java/org/jnbis/internal/record/reader/SignatureImageReader.java
    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    ===================================================================
    diff --git a/src/main/java/org/jnbis/internal/record/reader/SignatureImageReader.java b/src/main/java/org/jnbis/internal/record/reader/SignatureImageReader.java
    --- a/src/main/java/org/jnbis/internal/record/reader/SignatureImageReader.java (revision f5f2178)
    +++ b/src/main/java/org/jnbis/internal/record/reader/SignatureImageReader.java (revision fdef3ce413c46d149a0e2c32e38f04ed233a44ff)
    @@ -26,6 +26,30 @@
    dataSize += token.buffer.length - token.pos - 12;
    }

  •    //Image designation character (IDC)
    
  •    int idc = token.buffer[token.pos + 4];
    
  •    signatureImage.setImageDesignationCharacter(String.valueOf(idc));
    
  •    //Signature type (SIG)
    
  •    int sig = token.buffer[token.pos + 5];
    
  •    signatureImage.setSignatureType(String.valueOf(sig));
    
  •    //Signature representation type (SRT)
    
  •    int srt = token.buffer[token.pos + 6];
    
  •    signatureImage.setSignatureRepresentationType(String.valueOf(srt));
    
  •    //Image scanning resolution (ISR)
    
  •    int isr = token.buffer[token.pos + 7];
    
  •    signatureImage.setImageScanningResolution(String.valueOf(isr));
    
  •    //Horizontal line length (HLL)
    
  •    long hll = read2BytesAsInt(token, 8);
    
  •    signatureImage.setHorizontalLineLength(String.valueOf(hll));
    
  •    //Vertical line length (VLL)
    
  •    long vll = read2BytesAsInt(token, 10);
    
  •    signatureImage.setVerticalLineLength(String.valueOf(vll));
    
  •    byte[] data = new byte[dataSize];
       System.arraycopy(token.buffer, token.pos + 12, data, 0, data.length + 12 - 12);
    

Find out which record in Nist is List, which one is single item

Some of the records in a Nist file can appear more than one time (fingerprints for example) but some others can appear only once (transaction info).

In order to have a clean mode, we need to identify these records and convert the list to single times.

method encode

Dears,
why there is no a method to encode images like BMP , Jpg to WSQ formate

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.