2015-04-14 10 views
7

Próbowałem połączyć kod tak, aby rzeczywiście zapisać obraz z czujników linii papilarnych. Wypróbowałem już fora i to jest mój obecny kod, który zapisuje plik z prawidłowym rozmiarem pliku, ale kiedy go otworzę, to nie obraz odcisków palców raczej wygląda jak uszkodzony obraz. Oto, jak to wygląda.Obraz zapisany z czujnika linii papilarnych wydaje się być uszkodzony

enter image description here

Mój kod znajduje się poniżej. Każda pomoc zostanie doceniona. Jestem nowy w rozwoju systemu 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

[BITMAPINFOHEADER] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd318229.aspx) * "** Jeśli biCompression równa ** ** ** i BI_RGB bitmapa używa 8 bpp lub mniej, mapa bitowa ma tabelę kolorów natychmiast po strukturze ** BITMAPINFOHEADER ** Tabela kolorów składa się z tablicy ** RGBQUAD ** wartości. Rozmiar tablicy jest podany przez ** biClrUsed ** member. Jeśli ** biClrUsed ** wynosi zero, tablica zawiera maksymalną liczbę kolorów dla danej bitdepth, czyli 2^** biBitCount ** kolorów. "* – IInspectable

+0

to odcisk palca, który łączy się bezpośrednio z komputerem lub mikrokontroler? jak podłączyć odcisk palca do swojego systemu? –

+0

Nie, jest bezpośrednio podłączony do komputera za pomocą usb. –

Odpowiedz

2

IInspectable jest poprawne, korupcja wygląda to przychodzi z jawnej wykorzystaniem tabel kolorów:

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

Jeśli dane są faktycznie tylko 24-bitowy RGB, można zrobić info.biBitCount = 24; renderowanie poprawna bitmapa. Jeśli jest niższy (lub wyższy) niż to, musisz wykonać kilka konwersji. Możesz sprawdzić AnsiBdbHeader->PixelDepth, aby potwierdzić, że oczekiwany jest 8 bitów na piksel.

Wygląda również na to, że podanie AnsiBdbRecord->BlockLength do SaveBMP nie jest poprawne. Docs tego pola powiedzieć:

WINBIO_BDB_ANSI_381_RECORD structure
BlockLength
Zawiera liczbę bajtów w tej strukturze plus liczbę bajtów danych Przykładowy obraz.

Musisz więc koniecznie odjąć sizeof(WINBIO_BDB_ANSI_381_RECORD) przed przekazaniem go jako rozmiaru bufora bitmapy.

Notatka boczna, pamiętaj, aby zwolnić pamięć po wykonaniu przechwytywania.

WinBioFree(sample); 
WinBioCloseSession(sessionHandle); 
+0

Dane nie są RGB, skanery linii papilarnych generują obraz monochromatyczny. WINBIO_BDB_ANSI_381_HEADER.PixelDepth wskazuje liczbę bitów na piksel. Element ImageCompressionAlg jest również odpowiedni. –

Powiązane problemy