从指纹传感器保存的图像似乎已损坏

时间:2015-04-14 12:56:47

标签: windows winapi visual-c++

我一直在尝试整理代码以实际保存指纹传感器的图像。我已经尝试了论坛,这是我当前的代码,它保存文件的文件大小正确,但当我打开图像时,它不是指纹图像,而是看起来像一个损坏的图像。这是它的样子。

enter image description here

我的代码如下。任何帮助将不胜感激。我是Windows开发的新手。

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();
    }

1 个答案:

答案 0 :(得分:2)

IInspectable是正确的,腐败看起来像是来自你隐式使用颜色表:

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

如果您的数据实际上只是24位RGB,则可以info.biBitCount = 24;来渲染有效的位图。如果它低于(或高于),那么您将需要进行一些转换工作。您可以检查AnsiBdbHeader->PixelDepth以确认它是您期望的每像素8位。

看起来你向SaveBMP传递AnsiBdbRecord->BlockLength也不太对劲。这个领域的文档说:

  

WINBIO_BDB_ANSI_381_RECORD structure
  的块长度
  包含此结构中的字节数加上样本图像数据的字节数。

因此,在将其作为位图缓冲区大小传递之前,您需要确保减去sizeof(WINBIO_BDB_ANSI_381_RECORD)

旁注,请确保在捕获后释放所涉及的内存。

WinBioFree(sample);
WinBioCloseSession(sessionHandle);