2015-04-14 10 views
7

Ho cercato di mettere insieme il codice per salvare effettivamente l'immagine dai sensori di impronte digitali. Ho già provato i forum e questo è il mio codice corrente che salva il file con le dimensioni corrette del file ma quando apro l'immagine, la sua non immagine di impronta digitale sembra piuttosto un'immagine corrotta. Ecco come appare.L'immagine salvata dal sensore di impronte digitali sembra corrotta

enter image description here

Il mio codice è riportata qui sotto. Qualsiasi aiuto sarà apprezzato. Sono nuovo allo sviluppo di 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): * "Se ** ** biCompression uguale ** ** BI_RGB e la bitmap usa 8 bpp o meno, la bitmap ha una tabella di colori che segue immediatamente la struttura ** BITMAPINFOHEADER ** La tabella dei colori è costituita da una matrice di ** valori RGBQUAD **. La dimensione dell'array è data dal ** membro biClrUsed ** Se ** biClrUsed ** è zero, la matrice contiene il numero massimo di colori per il bitdepth specificato, ovvero 2^** colori biBitCount **. * – IInspectable

+0

è un'impronta digitale connessa direttamente a un computer o micro controller? come connetti le impronte digitali al tuo sistema? –

+0

No, è collegato direttamente al PC tramite USB. –

risposta

2

IInspectable è corretta, la corruzione sembra che sia proveniente dal vostro uso implicito di tavole a colori:

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

Se i dati sono in realtà solo a 24 bit RGB, si può fare info.biBitCount = 24; per rendere un bitmap valida. Se è inferiore (o superiore), dovrai eseguire un po 'di conversione. Puoi controllare AnsiBdbHeader->PixelDepth per confermare che sono gli 8 bit per pixel che ti aspetti.

Sembra inoltre che il passaggio di AnsiBdbRecord->BlockLength in SaveBMP non sia corretto. La documentazione per questo campo dicono:

WINBIO_BDB_ANSI_381_RECORD structure
BlockLength
contiene il numero di byte in questa struttura più il numero di byte di dati di immagine campione.

Quindi è necessario assicurarsi di sottrarre sizeof(WINBIO_BDB_ANSI_381_RECORD) prima di passarlo come dimensione del buffer bitmap.

Nota a margine, assicurarsi di liberare la memoria in questione dopo l'acquisizione.

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

I dati non sono RGB, gli scanner di impronte digitali generano un'immagine monocromatica. WINBIO_BDB_ANSI_381_HEADER.PixelDepth indica il numero di bit per pixel. Anche il membro ImageCompressionAlg è rilevante. –

Problemi correlati