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

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

最佳答案

IInspectable 是正确的,损坏看起来像是来自您对颜色表的隐式使用:

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

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

看起来您将 AnsiBdbRecord->BlockLength 传递给 SaveBMP 也不太正确。该字段的文档说:

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

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

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

WinBioFree(sample);
WinBioCloseSession(sessionHandle);

关于windows - 从指纹传感器保存的图像似乎已损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29627931/

相关文章:

c++ - 错误: “expression must have class type” & “left of must have class/struct/union”

c - WM_MOUSEMOVE 消息处理

windows - inno setup创建的vb脚本快捷方式出错

c# - 为什么这段代码在 Windows 7 上有效,但在 Windows XP 上却无效?

C#从上下文菜单Windows资源管理器中选定的文件/文件夹中检索文件/文件夹路径

c++ - 如何更改线程的名称

c++ - 将焦点转移到另一个程序 Windows API

c++ - ATL 宏仅适用于开发计算机

c++ - 如何用C++编写控制台终端

python - 使用什么部署框架?