Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image saved from Fingerprint sensor seems corrupted

I have been trying to put together code to actually save image from fingerprint sensors. I have already tried forums and this is my current code which saves file with correct file size but When i open the image, Its not image of fingerprint rather it looks like a corrupted image. Here is what it looks like.

enter image description here

My code is given below. Any help will be appreciated. I am new to windows development.

bool SaveBMP(BYTE* Buffer, int width, int height, long paddedsize, LPCTSTR bmpfile)
    {
        BITMAPFILEHEADER bmfh;
        BITMAPINFOHEADER info;
        memset(&bmfh, 0, sizeof(BITMAPFILEHEADER));
        memset(&info, 0, sizeof(BITMAPINFOHEADER));
        //Next we fill the file header with data:
        bmfh.bfType = 0x4d42;       // 0x4d42 = 'BM'
        bmfh.bfReserved1 = 0;
        bmfh.bfReserved2 = 0;
        bmfh.bfSize = sizeof(BITMAPFILEHEADER) +
            sizeof(BITMAPINFOHEADER) + paddedsize;
        bmfh.bfOffBits = 0x36;
        //and the info header:
        info.biSize = sizeof(BITMAPINFOHEADER);
        info.biWidth = width;
        info.biHeight = height;
        info.biPlanes = 1;

        info.biBitCount = 8;
        info.biCompression = BI_RGB;

        info.biSizeImage = 0;
        info.biXPelsPerMeter = 0x0ec4;
        info.biYPelsPerMeter = 0x0ec4;
        info.biClrUsed = 0;

        info.biClrImportant = 0;

        HANDLE file = CreateFile(bmpfile, GENERIC_WRITE, FILE_SHARE_READ,
            NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

        //Now we write the file header and info header:
        unsigned long bwritten;
        if (WriteFile(file, &bmfh, sizeof(BITMAPFILEHEADER),
            &bwritten, NULL) == false)
        {
            CloseHandle(file);
            return false;
        }

        if (WriteFile(file, &info, sizeof(BITMAPINFOHEADER),
            &bwritten, NULL) == false)
        {
            CloseHandle(file);
            return false;
        }
        //and finally the image data:
        if (WriteFile(file, Buffer, paddedsize, &bwritten, NULL) == false)
        {
            CloseHandle(file);
            return false;
        }
        //Now we can close our function with
        CloseHandle(file);
        return true;
    }

    HRESULT CaptureSample()
    {
        HRESULT hr = S_OK;
        WINBIO_SESSION_HANDLE sessionHandle = NULL;
        WINBIO_UNIT_ID unitId = 0;
        WINBIO_REJECT_DETAIL rejectDetail = 0;
        PWINBIO_BIR sample = NULL;
        SIZE_T sampleSize = 0;

        // Connect to the system pool. 
        hr = WinBioOpenSession(
            WINBIO_TYPE_FINGERPRINT,    // Service provider
            WINBIO_POOL_SYSTEM,         // Pool type
            WINBIO_FLAG_RAW,            // Access: Capture raw data
            NULL,                       // Array of biometric unit IDs
            0,                          // Count of biometric unit IDs
            WINBIO_DB_DEFAULT,          // Default database
            &sessionHandle              // [out] Session handle
            );


        // Capture a biometric sample.
        wprintf_s(L"\n Calling WinBioCaptureSample - Swipe sensor...\n");
        hr = WinBioCaptureSample(
            sessionHandle,
            WINBIO_NO_PURPOSE_AVAILABLE,
            WINBIO_DATA_FLAG_RAW,
            &unitId,
            &sample,
            &sampleSize,
            &rejectDetail
            );

        wprintf_s(L"\n Swipe processed - Unit ID: %d\n", unitId);
        wprintf_s(L"\n Captured %d bytes.\n", sampleSize);

        PWINBIO_BIR_HEADER BirHeader = (PWINBIO_BIR_HEADER)(((PBYTE)sample) + sample->HeaderBlock.Offset);
        PWINBIO_BDB_ANSI_381_HEADER AnsiBdbHeader = (PWINBIO_BDB_ANSI_381_HEADER)(((PBYTE)sample) + sample->StandardDataBlock.Offset);
        PWINBIO_BDB_ANSI_381_RECORD AnsiBdbRecord = (PWINBIO_BDB_ANSI_381_RECORD)(((PBYTE)AnsiBdbHeader) + sizeof(WINBIO_BDB_ANSI_381_HEADER));
        PBYTE firstPixel = (PBYTE)((PBYTE)AnsiBdbRecord) + sizeof(WINBIO_BDB_ANSI_381_RECORD);
        SaveBMP(firstPixel, AnsiBdbRecord->HorizontalLineLength, AnsiBdbRecord->VerticalLineLength, AnsiBdbRecord->BlockLength, "D://test.bmp");

        wprintf_s(L"\n Press any key to exit.");
        _getch();
    }
like image 951
Abhishek Sharma Avatar asked Apr 14 '15 12:04

Abhishek Sharma


People also ask

How do you fix a fingerprint sensor error?

To do so: Go to the “Settings menu” and then search for fingerprint data or management. After that, delete the fingerprint data and try to add a new fingerprint again. After completing it, restart your device and check whether it works or not.

Can we repair fingerprint sensor?

Like most hardware-related device problems, a broken fingerprint sensor can be fixed at home. However, this is not recommended for someone who hasn't familiarized themselves with the tools and knowledge required, so it's best to consider the previous option if your tech and DIY knowledge aren't great.


1 Answers

IInspectable is correct, the corruption looks like it's coming from your implicit use of color tables:

info.biBitCount = 8;
info.biCompression = BI_RGB;

If your data is actually just 24-bit RGB, you can do info.biBitCount = 24; to render a valid bitmap. If it's lower (or higher) than that, then you'll need to do some conversion work. You can check AnsiBdbHeader->PixelDepth to confirm that it's the 8 bits per pixel that you expect.

It also looks like your passing AnsiBdbRecord->BlockLength to SaveBMP isn't quite right. The docs for this field say:

WINBIO_BDB_ANSI_381_RECORD structure
BlockLength
Contains the number of bytes in this structure plus the number of bytes of sample image data.

So you'll want to make sure to subtract sizeof(WINBIO_BDB_ANSI_381_RECORD) before passing it as your bitmap buffer size.

Side note, make sure you free the memory involved after the capture.

WinBioFree(sample);
WinBioCloseSession(sessionHandle);
like image 163
Brian Holley Avatar answered Oct 26 '22 21:10

Brian Holley