I’m trying to get an image from the fingerprint scanner Futronic FS88h, here is what I’ve been doing until now.
from ctypes import windll, wintypes from os import device_encoding import ctypes lib = ctypes.WinDLL('ftrScanAPI.dll') FTRHANDLE = ctypes.c_void_p # classes class FTRSCAN_DEVICE_INFO(ctypes.Structure): _fields_ = [ ("dwStructSize", FTR_DWORD), ("byDeviceCompatibility", FTR_BYTE), ("wPixelSizeX", FTR_WORD), ("wPixelSizeY", FTR_WORD) ] PFTRSCAN_DEVICE_INFO = ctypes.POINTER(FTRSCAN_DEVICE_INFO) class FTRSCAN_FAKE_REPLICA_PARAMETERS(ctypes.Structure): _fields_ = [ ("bCalculated", FTR_BOOL), ("nCalculatedSum1", ctypes.c_int), ("nCalculatedSumFuzzy", ctypes.c_int), ("nCalculatedSumEmpty", ctypes.c_int), ("nCalculatedSum2", ctypes.c_int), ("dblCalculatedTremor", ctypes.c_double), ("dblCalculatedValue", ctypes.c_double), ] PFTRSCAN_FAKE_REPLICA_PARAMETERS = ctypes.POINTER(FTRSCAN_FAKE_REPLICA_PARAMETERS) fake_replica = FTRSCAN_FAKE_REPLICA_PARAMETERS(0, 0, 0, 0, 0, 0, 0) class FTRSCAN_FRAME_PARAMETERS(ctypes.Structure): _fields_ = [ ("nContrastOnDose2", ctypes.c_int), ("nContrastOnDose4", ctypes.c_int), ("nDose", ctypes.c_int), ("nBrightnessOnDose1", ctypes.c_int), ("nBrightnessOnDose2", ctypes.c_int), ("nBrightnessOnDose3", ctypes.c_int), ("nBrightnessOnDose4", ctypes.c_int), ("FakeReplicaParams", FTRSCAN_FAKE_REPLICA_PARAMETERS), ] PFTRSCAN_FRAME_PARAMETERS = ctypes.POINTER(FTRSCAN_FRAME_PARAMETERS) if __name__ == "__main__": lib.ftrScanOpenDevice.argtypes = [] lib.ftrScanOpenDevice.restype = FTRHANDLE h_device = lib.ftrScanOpenDevice() frame_parameters = FTRSCAN_FRAME_PARAMETERS(0, 0, 0, 0, 0, 0, 0, fake_replica, 0) lib.ftrScanIsFingerPresent.argtypes = [FTRHANDLE, PFTRSCAN_FRAME_PARAMETERS] lib.ftrScanIsFingerPresent.restype = FTR_BOOL if lib.ftrScanIsFingerPresent(h_device, ctypes.byref(frame_parameters)): print("nFinger parameters") print(f"1: {frame_parameters.nContrastOnDose2}") print(f"2: {frame_parameters.nContrastOnDose4}") print(f"3: {frame_parameters.nDose}") print(f"4: {frame_parameters.nBrightnessOnDose1}") print(f"5: {frame_parameters.nBrightnessOnDose2}") print(f"6: {frame_parameters.nBrightnessOnDose3}") print(f"7: {frame_parameters.nBrightnessOnDose4}n")
With this I’m able to check if the finger is present and it actually retrieves some info, but I need to get the image from the device and I’m not quite sure how to do it, I’ve been trying this:
lib.ftrScanGetImage.argtypes = [FTRHANDLE] lib.ftrScanGetImage.restypes = wintypes.BOOL get_image = lib.ftrScanGetImage(h_device) print(get_image)
But this only returns a bool, I’d love to know how to get the image or some data that I can convert into a image. This is the .dll that I’m using.
I’ve found this piece of code that gets the image, however, I don’t know how I should port it to Python, here’s the piece of code from this question.
int getRawImage(unsigned char *pBuffer); int writeJPEGBFile(unsigned char *idata, char *ofile); int main(int argc, char** argv) { unsigned char *rawData; // Removed the NULL assignment char filename[MAXPATHLEN] = "/home/user/tst/img.jpg"; // Set the size of rawData - loadImageSize() sets the value of the ImageSize class variable. loadImageSize(); rawData = (unsigned char *) malloc(ImageSize.nImageSize); getRawImage(rawData); // This works now writeJPEGBFile(rawData, filename); free(rawData); return 0; } int getRawImage(unsigned char *pBuffer) { void *hDevice; hDevice = scanOpenDevice(); // Removed code for simplification scanGetFrame(hDevice, pBuffer, NULL) scanCloseDevice(hDevice); return 0; } int writeJPEGBFile(unsigned char *idata, char *ofile) { // JPEG code goes here return 0; }
Advertisement
Answer
There’s a C# example here. Using it as a reference:
# Relevant definitions from the library header: # #define FTR_API_PREFIX # #define FTR_API __stdcall # # typedef void* FTRHANDLE; # typedef void* FTR_PVOID; # typedef int FTR_BOOL; # # typedef struct # { # int nWidth; # int nHeight; # int nImageSize; # } FTRSCAN_IMAGE_SIZE, *PFTRSCAN_IMAGE_SIZE; # # FTR_API_PREFIX FTRHANDLE FTR_API ftrScanOpenDevice(); # FTR_API_PREFIX void FTR_API ftrScanCloseDevice( FTRHANDLE ftrHandle ); # FTR_API_PREFIX FTR_BOOL FTR_API ftrScanGetImageSize( FTRHANDLE ftrHandle, PFTRSCAN_IMAGE_SIZE pImageSize ); # FTR_API_PREFIX FTR_BOOL FTR_API ftrScanGetImage( FTRHANDLE ftrHandle, int nDose, FTR_PVOID pBuffer ); import ctypes as ct # A type-safe handle class FTRHANDLE(ct.c_void_p): pass class FTRSCAN_IMAGE_SIZE(ct.Structure): _fields_ = (('nWidth', ct.c_int), ('nHeight', ct.c_int), ('nImageSize', ct.c_int)) PFTRSCAN_IMAGE_SIZE = ct.POINTER(FTRSCAN_IMAGE_SIZE) lib = ct.WinDLL('./ftrScanAPI') # due to __stdcall, only matters if 32-bit Python and DLL lib.ftrScanOpenDevice.argtypes = () lib.ftrScanOpenDevice.restype = FTRHANDLE lib.ftrScanCloseDevice.argtypes = FTRHANDLE, lib.ftrScanCloseDevice.restype = None lib.ftrScanGetImageSize.argtypes = FTRHANDLE, PFTRSCAN_IMAGE_SIZE lib.ftrScanGetImageSize.restype = ct.c_int lib.ftrScanGetImage.argtypes = FTRHANDLE, ct.c_int, ct.c_void_p lib.ftrScanGetImage.restype = ct.c_int handle = lib.ftrScanOpenDevice() try: size = FTRSCAN_IMAGE_SIZE() # allocate output parameter storage if not lib.ftrScanGetImageSize(handle, ct.byref(size)): raise RuntimeError('get size failed') NDos = 4 # I don't know what this parameter means, from C# example buffer = ct.create_string_buffer(size.nImageSize) # storage for image if not lib.ftrScanGetImage(handle, NDos, buffer): raise RuntimeError('get image failed') # buffer contains the image data now finally: lib.ftrScanCloseDevice(handle)