diff --git a/examples/sendvirtimg.py b/examples/sendvirtimg.py new file mode 100755 index 0000000..ca950f1 --- /dev/null +++ b/examples/sendvirtimg.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 + +# This script can be used together with the virtual_imgdev to simulate an +# image based fingerprint reader. +# +# To use, set the FP_VIRTUAL_IMGDEV environment variable for both the +# libfprint using program (e.g. fprintd) and this script. +# +# Usually this would work by adding it into the systemd unit file. The +# best way of doing so is to create +# /etc/systemd/system/fprintd.service.d/fprintd-test.conf +# +# [Service] +# RuntimeDirectory=fprint +# Environment=FP_VIRTUAL_IMGDEV=/run/fprint/virtimg_sock +# Environment=G_MESSAGES_DEBUG=all +# ReadWritePaths=$RUNTIME_DIR +# +# After that run: +# +# systemctl daemon-reload +# systemctl restart fprintd.service +# +# You may also need to disable selinux. +# +# Then run this script with e.g. +# FP_VIRTUAL_IMGDEV=/run/fprint/virtimg_sock ./sendvirtimg.py prints/whorl.png + + + +import cairo +import sys +import os +import socket +import struct + +if len(sys.argv) == 2: + png = cairo.ImageSurface.create_from_png(sys.argv[1]) + + # Cairo wants 4 byte aligned rows, so just add a few pixel if necessary + w = png.get_width() + h = png.get_height() + w = (w + 3) // 4 * 4 + h = (h + 3) // 4 * 4 + img = cairo.ImageSurface(cairo.Format.A8, w, h) + cr = cairo.Context(img) + + cr.set_source_rgba(1, 1, 1, 1) + cr.paint() + + cr.set_source_rgba(0, 0, 0, 0) + cr.set_operator(cairo.OPERATOR_SOURCE) + + cr.set_source_surface(png) + cr.paint() +else: + sys.stderr.write('You need to pass a PNG with an alpha channel!\n') + sys.exit(1) + +def write_dbg_img(): + dbg_img_rgb = cairo.ImageSurface(cairo.Format.RGB24, img.get_width(), img.get_height()) + dbg_cr = cairo.Context(dbg_img_rgb) + dbg_cr.set_source_rgb(0, 0, 0) + dbg_cr.paint() + dbg_cr.set_source_rgb(1, 1, 1) + dbg_cr.mask_surface(img, 0, 0) + + dbg_img_rgb.write_to_png('/tmp/test.png') + +#write_dbg_img() + +# Send image through socket +sockaddr = os.environ['FP_VIRTUAL_IMGDEV'] + +sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) +sock.connect(sockaddr) + +mem = img.get_data() +mem = mem.tobytes() +assert len(mem) == img.get_width() * img.get_height() + +encoded_img = struct.pack('ii', img.get_width(), img.get_height()) +encoded_img += mem + +sock.sendall(encoded_img) +