I’m trying to get an image from the fingerprint scanner Futronic FS88h, here is what I’ve been doing until now.
JavaScript
x
63
63
1
from ctypes import windll, wintypes
2
from os import device_encoding
3
import ctypes
4
5
lib = ctypes.WinDLL('ftrScanAPI.dll')
6
7
FTRHANDLE = ctypes.c_void_p
8
9
# classes
10
11
class FTRSCAN_DEVICE_INFO(ctypes.Structure):
12
_fields_ = [
13
("dwStructSize", FTR_DWORD),
14
("byDeviceCompatibility", FTR_BYTE),
15
("wPixelSizeX", FTR_WORD),
16
("wPixelSizeY", FTR_WORD)
17
]
18
PFTRSCAN_DEVICE_INFO = ctypes.POINTER(FTRSCAN_DEVICE_INFO)
19
20
class FTRSCAN_FAKE_REPLICA_PARAMETERS(ctypes.Structure):
21
_fields_ = [
22
("bCalculated", FTR_BOOL),
23
("nCalculatedSum1", ctypes.c_int),
24
("nCalculatedSumFuzzy", ctypes.c_int),
25
("nCalculatedSumEmpty", ctypes.c_int),
26
("nCalculatedSum2", ctypes.c_int),
27
("dblCalculatedTremor", ctypes.c_double),
28
("dblCalculatedValue", ctypes.c_double),
29
]
30
PFTRSCAN_FAKE_REPLICA_PARAMETERS = ctypes.POINTER(FTRSCAN_FAKE_REPLICA_PARAMETERS)
31
fake_replica = FTRSCAN_FAKE_REPLICA_PARAMETERS(0, 0, 0, 0, 0, 0, 0)
32
33
class FTRSCAN_FRAME_PARAMETERS(ctypes.Structure):
34
_fields_ = [
35
("nContrastOnDose2", ctypes.c_int),
36
("nContrastOnDose4", ctypes.c_int),
37
("nDose", ctypes.c_int),
38
("nBrightnessOnDose1", ctypes.c_int),
39
("nBrightnessOnDose2", ctypes.c_int),
40
("nBrightnessOnDose3", ctypes.c_int),
41
("nBrightnessOnDose4", ctypes.c_int),
42
("FakeReplicaParams", FTRSCAN_FAKE_REPLICA_PARAMETERS),
43
]
44
PFTRSCAN_FRAME_PARAMETERS = ctypes.POINTER(FTRSCAN_FRAME_PARAMETERS)
45
46
if __name__ == "__main__":
47
lib.ftrScanOpenDevice.argtypes = []
48
lib.ftrScanOpenDevice.restype = FTRHANDLE
49
h_device = lib.ftrScanOpenDevice()
50
51
frame_parameters = FTRSCAN_FRAME_PARAMETERS(0, 0, 0, 0, 0, 0, 0, fake_replica, 0)
52
lib.ftrScanIsFingerPresent.argtypes = [FTRHANDLE, PFTRSCAN_FRAME_PARAMETERS]
53
lib.ftrScanIsFingerPresent.restype = FTR_BOOL
54
if lib.ftrScanIsFingerPresent(h_device, ctypes.byref(frame_parameters)):
55
print("nFinger parameters")
56
print(f"1: {frame_parameters.nContrastOnDose2}")
57
print(f"2: {frame_parameters.nContrastOnDose4}")
58
print(f"3: {frame_parameters.nDose}")
59
print(f"4: {frame_parameters.nBrightnessOnDose1}")
60
print(f"5: {frame_parameters.nBrightnessOnDose2}")
61
print(f"6: {frame_parameters.nBrightnessOnDose3}")
62
print(f"7: {frame_parameters.nBrightnessOnDose4}n")
63
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:
JavaScript
1
5
1
lib.ftrScanGetImage.argtypes = [FTRHANDLE]
2
lib.ftrScanGetImage.restypes = wintypes.BOOL
3
get_image = lib.ftrScanGetImage(h_device)
4
print(get_image)
5
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.
JavaScript
1
33
33
1
int getRawImage(unsigned char *pBuffer);
2
int writeJPEGBFile(unsigned char *idata, char *ofile);
3
4
int main(int argc, char** argv) {
5
unsigned char *rawData; // Removed the NULL assignment
6
char filename[MAXPATHLEN] = "/home/user/tst/img.jpg";
7
8
// Set the size of rawData - loadImageSize() sets the value of the ImageSize class variable.
9
loadImageSize();
10
rawData = (unsigned char *) malloc(ImageSize.nImageSize);
11
12
getRawImage(rawData);
13
// This works now
14
writeJPEGBFile(rawData, filename);
15
free(rawData);
16
return 0;
17
}
18
19
int getRawImage(unsigned char *pBuffer) {
20
void *hDevice;
21
22
hDevice = scanOpenDevice();
23
// Removed code for simplification
24
scanGetFrame(hDevice, pBuffer, NULL)
25
scanCloseDevice(hDevice);
26
return 0;
27
}
28
29
int writeJPEGBFile(unsigned char *idata, char *ofile) {
30
// JPEG code goes here
31
return 0;
32
}
33
Advertisement
Answer
There’s a C# example here. Using it as a reference:
JavaScript
1
57
57
1
# Relevant definitions from the library header:
2
3
# #define FTR_API_PREFIX
4
# #define FTR_API __stdcall
5
#
6
# typedef void* FTRHANDLE;
7
# typedef void* FTR_PVOID;
8
# typedef int FTR_BOOL;
9
#
10
# typedef struct
11
# {
12
# int nWidth;
13
# int nHeight;
14
# int nImageSize;
15
# } FTRSCAN_IMAGE_SIZE, *PFTRSCAN_IMAGE_SIZE;
16
#
17
# FTR_API_PREFIX FTRHANDLE FTR_API ftrScanOpenDevice();
18
# FTR_API_PREFIX void FTR_API ftrScanCloseDevice( FTRHANDLE ftrHandle );
19
# FTR_API_PREFIX FTR_BOOL FTR_API ftrScanGetImageSize( FTRHANDLE ftrHandle, PFTRSCAN_IMAGE_SIZE pImageSize );
20
# FTR_API_PREFIX FTR_BOOL FTR_API ftrScanGetImage( FTRHANDLE ftrHandle, int nDose, FTR_PVOID pBuffer );
21
22
import ctypes as ct
23
24
# A type-safe handle
25
class FTRHANDLE(ct.c_void_p):
26
pass
27
28
class FTRSCAN_IMAGE_SIZE(ct.Structure):
29
_fields_ = (('nWidth', ct.c_int),
30
('nHeight', ct.c_int),
31
('nImageSize', ct.c_int))
32
33
PFTRSCAN_IMAGE_SIZE = ct.POINTER(FTRSCAN_IMAGE_SIZE)
34
35
lib = ct.WinDLL('./ftrScanAPI') # due to __stdcall, only matters if 32-bit Python and DLL
36
lib.ftrScanOpenDevice.argtypes = ()
37
lib.ftrScanOpenDevice.restype = FTRHANDLE
38
lib.ftrScanCloseDevice.argtypes = FTRHANDLE,
39
lib.ftrScanCloseDevice.restype = None
40
lib.ftrScanGetImageSize.argtypes = FTRHANDLE, PFTRSCAN_IMAGE_SIZE
41
lib.ftrScanGetImageSize.restype = ct.c_int
42
lib.ftrScanGetImage.argtypes = FTRHANDLE, ct.c_int, ct.c_void_p
43
lib.ftrScanGetImage.restype = ct.c_int
44
45
handle = lib.ftrScanOpenDevice()
46
try:
47
size = FTRSCAN_IMAGE_SIZE() # allocate output parameter storage
48
if not lib.ftrScanGetImageSize(handle, ct.byref(size)):
49
raise RuntimeError('get size failed')
50
NDos = 4 # I don't know what this parameter means, from C# example
51
buffer = ct.create_string_buffer(size.nImageSize) # storage for image
52
if not lib.ftrScanGetImage(handle, NDos, buffer):
53
raise RuntimeError('get image failed')
54
# buffer contains the image data now
55
finally:
56
lib.ftrScanCloseDevice(handle)
57