87 lines
2.2 KiB
Python
87 lines
2.2 KiB
Python
|
#!/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)
|
||
|
|