2016-12-08 43 views
1

我正在使用biometrics SDK。我將頭文件轉換爲delphi以使用dll。從回調函數的參數中獲取值

它看起來是這樣的:

const 
{VrBio_EventType} 
    VRBIO_CAPTURE_EVENT_UNPLUG    = $001; {Fingerprint scanner unplugged from the computer.} 
    VRBIO_CAPTURE_EVENT_PLUG     = $002; {Fingerprint scanner plugged on the computer.} 
    VRBIO_CAPTURE_EVENT_REMOVED    = $004; {Finger removed from the fingerprint scanner.} 
    VRBIO_CAPTURE_EVENT_PLACED    = $008; {Finger placed on the fingerprint scanner.} 
    VRBIO_CAPTURE_EVENT_IMAGE_FRAME   = $10; {A fingerprint frame was captured on the fingerprint scanner.} 
    VRBIO_CAPTURE_EVENT_IMAGE_CAPTURED  = $020; {A fingerprint image was captured on the fingerprint scanner.} 
    VRBIO_CAPTURE_EVENT_FAKE_FINGER_DETECTED = $400; {A false finger has been detected on the sensor} 
    VRBIO_CAPTURE_EVENT_FAKE_FINGER_REMOVED = $800; {A false finger has been removed from the sensor} 

type 

(* Stores the parameters of the ISO 19794-4 image format. @see VGetReaderProperties @see VrBio_ReaderProperty 
typedef struct 
{ 
    /** @see VrBio_ISO197944CompressionMode*/ 
    int compressionMode; 
    /** @see VrBio_ISO197944ImpressionType*/ 
    int impressionType; 
    /** @see VrBio_ISO197944FingerPosition*/  
    int fingerPosition; 

}VrBio_ISO197944Parameters; 
*) 

    PISO197944Parameters = ^TISO197944Parameters; 
    TISO197944Parameters = record 
     compressionMode: Integer; { @see VrBio_ISO197944CompressionMode} 
     impressionType: Integer; { @see VrBio_ISO197944ImpressionType} 
     fingerPosition: Integer; { @see VrBio_ISO197944FingerPosition} 
    end; 

(* Represents a biometric image. @see VrBio_CaptureEventCallback \ref VSyncCapture 
struct VrBio_BiometricImage 
{ 
    /** Image width.*/ 
    int width; 
    /**Image height*/ 
    int height; 
    /**Image resolution in dpi. For the obsolete functions, use pixels/cm.*/ 
    int resolution; 
    /**Number of channels in the image. Fingerprint images should always be grayscale, so this value is always 1.*/ 
    int channels; 
    /**Biometric modality. 
    * Always use VRBIO_BIOMETRIC_MODALITY_FINGERPRINT. 
    * \ref VrBio_BiometricModality. 
    */ 
    int biometricModality; 
    /**Scanner type. 
    * \ref VrBio_ScannerType. 
    */ 
    int scannerType; 
    /**Formato de imagem: Formato da imagem. 
    *\ ref VrBio_ImageFormat.*/ 
    int imageFormat; 
    /**Size of the buffer*/ 
    int bufferSize; 
    /**Compression rate. Valid for images that allow compression. 
    * \ref VrBio_CompressionRate 
    */ 
    int compressionRate; 
/**Quality of the fingerprint image. 
    * \ref VrBio_FingerQuality 
    */ 
    int fingerQuality; 

    /** Only valid if the image if imageFormat is \ref VrBio_ImageFormat::VRBIO_IMAGEFORMAT_ISO19794_4 
    *\ref VrBio_ISO197944Parameters 
    */ 
    VrBio_ISO197944Parameters* ISO197944_parameters; 

    /** Buffer storing the pixels of the image. 
    The position(x,y,c) of a pixel is y*width*channels+x*channels+c. 
    */ 
    unsigned char* buffer; 

    /**Reserved for future use*/ 
    void* reserved; 
}; 

typedef struct VrBio_BiometricImage VrBio_BiometricImage; 
*) 
    PBiometricImage = ^TBiometricImage; 
    TBiometricImage = record 
    width: Integer;        { Image width. } 
    height: Integer;       { Image height } 
    resolution: Integer;      { Image resolution in dpi. For the obsolete functions, use pixels/cm.} 
    channels: Integer;       { Number of channels in the image. Fingerprint images should always be grayscale, so this value is always 1. } 
    biometricModality: Integer;     { Biometric modality. Always use VRBIO_BIOMETRIC_MODALITY_FINGERPRINT. \ref VrBio_BiometricModality. } 
    scannerType: Integer;      { Scanner type. \ref VrBio_ScannerType. } 
    imageFormat: Integer;      { Formato de imagem: Formato da imagem. \ ref VrBio_ImageFormat. } 
    bufferSize: Integer;      { Size of the buffer } 
    compressionRate: Integer;     { Compression rate. Valid for images that allow compression. \ref VrBio_CompressionRate } 
    fingerQuality: Integer;      { Quality of the fingerprint image. \ref VrBio_FingerQuality } 
    ISO197944_parameters: PISO197944Parameters; { Only valid if the image if imageFormat is \ref VrBio_ImageFormat::VRBIO_IMAGEFORMAT_ISO19794_4 \ref VrBio_ISO197944Parameters } 
    buffer: PByte;        { Buffer storing the pixels of the image. The position(x,y,c) of a pixel is y*width*channels+x*channels+c. } 
    reserved: Pointer;       { Reserved for future use } 
    end; 

(* 
#include "VTypes.h" 

#ifdef WIN32 
#define DLLIMPORT extern "C" __declspec(dllimport) int __stdcall 
#else 
#define DLLIMPORT extern "C" 
#endif 
*) 

{ Callback function that receives events.. 
typedef void (*VrBio_CaptureEventCallback) (
        int eventType, 
      const char* readerName, 
    VrBio_BiometricImage* image, 
      const void* userData) 
} 
    TCaptureEventCallback = procedure(eventType: Integer; readerName: PAnsiChar; image: PBiometricImage; userData: Pointer); stdcall; 

{ Function responsible for initializing the SDK. This function MUST be called before calling any other method, except \ref VInstallLicense 
    DLLIMPORT VStartSDK(VrBio_CaptureEventCallback eventCallback); 
} 
    function VStartSDK(eventCallback: TCaptureEventCallback): Integer; stdcall; 

{ Function responsible for finalizing the SDK. This function should be called when the SDK is not needed in the application anymore. 
    DLLIMPORT VStopSDK(); 
} 
    function VStopSDK(): Integer; stdcall; 

{ Function responsible for starting the capture on a specific fingerprint reader. 
    After calling this function, the application is able to receive events. 
    DLLIMPORT VStartReader(const char* readerName); 
} 
    function VStartReader(readerName: PAnsiChar): Integer; stdcall; 

使用它看起來像這樣:

implementation 

{$R *.dfm} 

procedure EventCallback(eventType: Integer; readerName: PAnsiChar; image: PBiometricImage; userData: Pointer); stdcall; 
begin 
    case eventType of 
    VRBIO_CAPTURE_EVENT_UNPLUG:    Form1.Memo1.Lines.Add('Leitor desconectado!'); 
    VRBIO_CAPTURE_EVENT_REMOVED:    Form1.Memo1.Lines.Add('Dedo removido!'); 
    VRBIO_CAPTURE_EVENT_PLACED:    Form1.Memo1.Lines.Add('Dedo detectado!'); 
    VRBIO_CAPTURE_EVENT_IMAGE_FRAME:   Form1.Memo1.Lines.Add('Frame capturado!'); 
    VRBIO_CAPTURE_EVENT_IMAGE_CAPTURED:  Form1.Memo1.Lines.Add('Imagem capturada!'); 
    VRBIO_CAPTURE_EVENT_FAKE_FINGER_DETECTED: Form1.Memo1.Lines.Add('Dedo falso detectado!'); 
    VRBIO_CAPTURE_EVENT_FAKE_FINGER_REMOVED: Form1.Memo1.Lines.Add('Dedo falso removido!'); 

    VRBIO_CAPTURE_EVENT_PLUG: 
    begin 
     VStartReader(readerName); 
     Form1.Memo1.Lines.Add('Leitor conectado!'); 
    end; 

    end; 
end; 

procedure TForm1.Button2Click(Sender: TObject); 
begin 
    VStartSDK(EventCallback); 
end; 

我的問題:

我可以使用該應用程序並獲得PlugUnplugPlaced事件,但當我得到Image Captured事件時,我有一個acces vilation。 在正在運行的事件中,EventCallback參數圖像爲nil。 TBiometricImage記錄轉換是否正確?

如何將TBiometricImage緩衝區轉換爲TBitmap並在TImage中顯示捕獲的圖像?

回答

2

當我得到圖像捕捉事件我有一個acces vilation。在正在運行的事件中,EventCallback參數圖像爲零。 TBiometricImage記錄轉換是否正確?

單個字段被宣佈爲正常,但請仔細檢查Delphi記錄的對齊和填充是否與C/C++中結構使用的對齊和填充匹配。

而且,更重要的是,VrBio_CaptureEventCallback的typedef在C/C++聲明沒有指定的任何調用約定,所以它會使用編譯器的默認慣例,這是通常__cdecl代替__stdcall(可在編譯器設置來配置)。在Delphi中,您聲明TCaptureEventCallback使用stdcall而不是cdecl。你必須確保你正確匹配調用約定(導出的DLL函數使用stdcall,所以你沒問題)。

如何將TBiometricImage緩衝區轉換爲TBitmap並在TImage中顯示捕獲的圖像?

SDK文檔沒有說明如何處理各種圖像格式。但是,僅查看結構聲明,buffer字段指向實際圖像數據,而imageFormat字段指示該數據的格式(還有一個VrBio_ImageFormat枚舉,您尚未翻譯)。因此,您首先需要查看imageFormat以瞭解如何解釋buffer

我確實看到VConvertImage()功能可用。所以你應該能夠將圖像轉換爲BMP格式,如果它們還沒有。根據SDK中的示例,看起來buffer數據可能是標準BMP文件格式,因此您可以嘗試將buffer複製到TMemoryStream,然後使用TBitmap.LoadFromStream()方法。

也有可用的GIF和JPG圖片格式,這可能是TGIFImageTJPEGImage,分別進行處理,甚至TWICImage,如果你想而無需將它們首先轉換爲BMP顯示掃描GIF/JPG圖片。還有一個RAW圖像格式可用(顯然你的圖像正在使用),但沒有標準的VCL TGraphic類來處理RAW圖像,但我認爲如果你環顧四周,可能會出現一些第三方類。

否則,你可以嘗試將圖像數據轉換爲BMP,如果需要的話,然後傳遞到buffer Win32 API的CreateBitmap/Indirect()CreateDibSection()功能,然後如果成功分配產生HBITMAPTBitmap.Handle財產。

+0

感謝您的回答。你對調用約定是正確的,我現在可以捕獲所有事件!其實還有其他的結構,我沒有把這個問題。 'VrBio_ImageFormat'看起來是這樣的: 'TImageFormat =( VRBIO_IMAGEFORMAT_UNKNOWN, VRBIO_IMAGEFORMAT_RAW, VRBIO_IMAGEFORMAT_BMP, VRBIO_IMAGEFORMAT_WSQ, VRBIO_IMAGEFORMAT_ISO19794_4, VRBIO_IMAGEFORMAT_JPEG, VRBIO_IMAGEFORMAT_TIFF, VRBIO_IMAGEFORMAT_PNG, VRBIO_IMAGEFORMAT_GIF);' 我得到的格式是'RAW' 。 –

+1

再次,沒有看到SDK文檔,任何人都無法知道任何給定圖像類型的像素數據是什麼樣子。也許'RAW'數據是RGB顏色,或者數據可能是實際的[RAW圖像](https://en.wikipedia.org/wiki/Raw_image_format)。 –

+1

我更新了我的答案。 –