2016-12-08 58 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

我更新了我的答案。 –