ZKTeco live20R fingerprint acquisition and identification is suitable for Google browser

Recently, the software project at hand needs to use fingerprint collector, so I went to a treasure and found that there are few mature fingerprint acquisition module manufacturers. Found a company with the highest sales. The price is also very cheap.

Most of them have desktop versions and Internet Explorer plug-ins, but none of them have Google browser versions. Depressed!

The project is based on Google browser, but Google browser does not support activeX controls. There are also ways to adapt activeX controls to Google browser on the Internet, but they are not guaranteed to be available. Based on the principle of no self-made on the Internet, I began the adaptation journey.

The curve saves the country. Since the browser is not good, go to the client. My idea is as follows:

1. Set up a websocket server on the desktop to listen to the websocket connection of a specific port. The server uses the officially provided CLIENT SDK to collect fingerprints. After the fingerprint is collected, the data is converted into a red fingerprint image, and then the image is converted into base64 data and transmitted to the client.

2. The client, i.e. Google browser, connects with the service of the server through websocket. After the client connects to the service, the server automatically records the connection ID, and sends the base64 format picture data to the browser through the ID. the browser converts the picture into a picture display. The effect is as follows

The above is the idea, just do it. Here is the code:

Server main program:

using libzkfpcsharp;
using Microsoft.Win32;
using SuperSocket.SocketBase.Config;
using SuperWebSocket;
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace FP_Service
{
    public partial class Form1 : Form
    {
        IntPtr mDevHandle = IntPtr.Zero;
        IntPtr FormHandle = IntPtr.Zero;
        string strBase64 = "";
        private bool isclose;
        bool bIsTimeToDie = false;
        byte[] FPBuffer;
        byte[][] RegTmps = new byte[3][];
        byte[] CapTmp = new byte[2048];
        int cbCapTmp = 2048;

        private int mfpWidth = 0;
        private int mfpHeight = 0;
        private WebSocketServer mWebSocketServer;
        private string mSessionID = "";
        const int MESSAGE_CAPTURED_OK = 0x0400 + 6;
        [DllImport("user32.dll", EntryPoint = "SendMessage")]
        public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
        public Form1()
        {
            InitializeComponent();
        }
      
        private void Form1_Load(object sender, EventArgs e)
        {

            FormHandle = this.Handle;
            base.Left = Screen.GetBounds(this).Width - base.Width - 5;
            base.Top = Screen.GetBounds(this).Height - base.Height - 50;
            FirstAutoRun(true);//Add to the system service and start up automatically.
            CheckAutoRun(Application.ExecutablePath, true);//Add to the system service and start up automatically.
            int ret = zkfperrdef.ZKFP_ERR_OK;
            if ((ret = zkfp2.Init()) == zkfperrdef.ZKFP_ERR_OK)
            {
                int nCount = zkfp2.GetDeviceCount();
                if (nCount < 0)
                {
                    zkfp2.Terminate();
                    label1.Text="No fingerprint collection device found!";
                }
            }
            else
            {
                label1.Text = "initialization failed, The return value is:" + ret;
            }
            //Setup();
            ServerConfig config = new ServerConfig{
                Ip = "127.0.0.1",
                Port = 8891,
                MaxConnectionNumber = 100,
                Name = "FPServer"
            };
            mWebSocketServer = new WebSocketServer();
            if (mWebSocketServer.Setup(config)) 
            { 
                label1.Text = "Service initialization succeeded.";
                mWebSocketServer.NewSessionConnected += MWebSocketServer_NewSessionConnected1;
            } 
            else {
                label1.Text = "Failed to initialize service!"; 
            }
           if( mWebSocketServer.Start()) { label1.Text = "The service was started successfully.";
              
            } else { label1.Text = "Failed to start service!"; }
         
            if (IntPtr.Zero == (mDevHandle = zkfp2.OpenDevice(0)))
            {
                label1.Text = "Failed to open the device!";
                return;
            }
            else
            {
                for (int i = 0; i < 3; i++)
                {
                    RegTmps[i] = new byte[2048];
                }
                byte[] paramValue = new byte[4];
                int size = 4;
                zkfp2.GetParameters(mDevHandle, 1, paramValue, ref size);
                zkfp2.ByteArray2Int(paramValue, ref mfpWidth);

                size = 4;
                zkfp2.GetParameters(mDevHandle, 2, paramValue, ref size);
                zkfp2.ByteArray2Int(paramValue, ref mfpHeight);

                FPBuffer = new byte[mfpWidth * mfpHeight];

                Thread captureThread = new Thread(new ThreadStart(DoCapture));
                captureThread.IsBackground = true;
                captureThread.Start();
                bIsTimeToDie = false;
                label1.Text = "device connected";
            }

        }
    
        private void DoCapture()
        {
            while (!bIsTimeToDie)
            {
                cbCapTmp = 2048;
                int ret = zkfp2.AcquireFingerprint(mDevHandle, FPBuffer, CapTmp, ref cbCapTmp);
             
                if (ret == zkfp.ZKFP_ERR_OK)
                {
                    SendMessage(FormHandle, MESSAGE_CAPTURED_OK, IntPtr.Zero, IntPtr.Zero);
                }
                Thread.Sleep(200);
            }
        }
        private string ToBase64(Bitmap bmp)
        {
            try
            {
                MemoryStream ms = new MemoryStream();
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                byte[] arr = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length);
                ms.Close();
                String strbaser64 = Convert.ToBase64String(arr);
                return strbaser64;
            }
            catch (Exception ex)
            {
                MessageBox.Show("switch views:" + ex.Message);
                return "";
            }
        }
        private static Bitmap UpdateColor(Bitmap bitmap)
        {
            int width = bitmap.Width;
            int height = bitmap.Height;
            Bitmap newmap = new Bitmap(width, height);
            Color pixel;
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    pixel = bitmap.GetPixel(i, j); // Gets the pixel color value of the original image
                    int r, g, b, a;
                    r = pixel.R;
                    g = pixel.G;
                    b = pixel.B;
                    a = pixel.A;
                   

                    // Determine whether it is a white background
                    if ( b > 120|| r > 120 || g > 120)
                    {
                        newmap.SetPixel(i, j, Color.FromArgb(0,255, 255, 255));
                    }
                    else
                    {
                        newmap.SetPixel(i, j, Color.Red);
                    }
                }
            }
            return newmap;
        }
        protected override void DefWndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case MESSAGE_CAPTURED_OK:
                    {
                        MemoryStream ms = new MemoryStream();
                        BitmapFormat.GetBitmap(FPBuffer, mfpWidth, mfpHeight, ref ms);
                        Bitmap bmp = UpdateColor( new Bitmap(ms));
                        //Bitmap bmp =new Bitmap(ms);
                        strBase64 = ToBase64(bmp);
                        pictureBox2.Image = bmp;

                        foreach (WebSocketSession sendSession in mWebSocketServer.GetAllSessions())
                        {
                            if (sendSession.SessionID.Equals(mSessionID))
                            {
                                sendSession.Send(strBase64);
                                break;
                            }
                        }

                    }
                    break;

                default:
                    base.DefWndProc(ref m);
                    break;
            }
        }

    
        private void MWebSocketServer_NewSessionConnected1(WebSocketSession session)
        {
            mSessionID = session.SessionID;//Client connection successfully saved ID to session
        }
     

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!isclose)
            {
                e.Cancel = true;
                base.Hide();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            isclose = true;
            this.Close();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                SetAutoRun(Application.ExecutablePath, false, true);
            }
            else
            {
                SetAutoRun(Application.ExecutablePath, true, true);
            }
        }
        public void SetAutoRun(string fileName, bool isAutoRun, bool isCurrentUser)
        {
            RegistryKey reg = null;
            try
            {
                if (!File.Exists(fileName))
                {
                    throw new Exception("Not File!");
                }
                string name = fileName.Substring(fileName.LastIndexOf("\\") + 1);
                if (isCurrentUser)
                {
                    reg = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                    if (reg == null)
                    {
                        reg = Registry.CurrentUser.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
                    }
                    if (isAutoRun)
                    {
                        if (reg.GetValue(name) == null)
                        {
                            reg.SetValue(name, fileName);
                        }
                        else if (!reg.GetValue(name).Equals(fileName))
                        {
                            reg.SetValue(name, fileName);
                        }
                    }
                    else
                    {
                        reg.DeleteValue(name);
                    }
                }
                else
                {
                    reg = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                    if (reg == null)
                    {
                        reg = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
                    }
                    if (isAutoRun)
                    {
                        if (reg.GetValue(name) == null)
                        {
                            reg.SetValue(name, fileName);
                        }
                        else if (!reg.GetValue(name).Equals(fileName))
                        {
                            reg.SetValue(name, fileName);
                        }
                    }
                    else
                    {
                        reg.DeleteValue(name);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
            finally
            {
                if (reg != null)
                {
                    reg.Close();
                }
            }
        }
        public void FirstAutoRun(bool isCurrentUser)
        {
            RegistryKey reg = null;
            try
            {
                string name = "Run";
                if (isCurrentUser)
                {
                    reg = Registry.CurrentUser.OpenSubKey("SOFTWARE\\FGTIT\\BioWebServer\\", true);
                    if (reg == null)
                    {
                        reg = Registry.CurrentUser.CreateSubKey("SOFTWARE\\FGTIT\\BioWebServer\\");
                    }
                    if (reg.GetValue(name) == null)
                    {
                        this.SetAutoRun(Application.ExecutablePath, true, true);
                        reg.SetValue(name, true);
                    }
                }
                else
                {
                    reg = Registry.LocalMachine.OpenSubKey("SOFTWARE\\FGTIT\\BioWebServer\\", true);
                    if (reg == null)
                    {
                        reg = Registry.LocalMachine.CreateSubKey("SOFTWARE\\FGTIT\\BioWebServer\\");
                    }
                    if (reg.GetValue(name) == null)
                    {
                        this.SetAutoRun(Application.ExecutablePath, true, false);
                        reg.SetValue(name, true);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
            finally
            {
                if (reg != null)
                {
                    reg.Close();
                }
            }
        }

        public void CheckAutoRun(string fileName, bool isCurrentUser)
        {
            RegistryKey reg = null;
            try
            {
                if (!File.Exists(fileName))
                {
                    throw new Exception("Not File!");
                }
                string name = fileName.Substring(fileName.LastIndexOf("\\") + 1);
                if (isCurrentUser)
                {
                    reg = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                    if (reg == null)
                    {
                        reg = Registry.CurrentUser.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
                    }
                    if (reg.GetValue(name) == null)
                    {
                        checkBox1.Checked = false;
                    }
                    else
                    {
                       checkBox1.Checked = true;
                    }
                }
                else
                {
                    reg = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                    if (reg == null)
                    {
                        reg = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
                    }
                    if (reg.GetValue(name) == null)
                    {
                        checkBox1.Checked = false;
                    }
                    else
                    {
                        checkBox1.Checked = true;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
            finally
            {
                if (reg != null)
                {
                    reg.Close();
                }
            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            mWebSocketServer.Stop();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int ret = zkfperrdef.ZKFP_ERR_OK;
            if ((ret = zkfp2.Init()) == zkfperrdef.ZKFP_ERR_OK)
            {
                int nCount = zkfp2.GetDeviceCount();
                if (nCount < 0)
                {
                    zkfp2.Terminate();
                    label1.Text = "No fingerprint collection device found!";
                }
            }
            else
            {
                label1.Text = "initialization failed, The return value is:" + ret;
            }
        }

        private void notifyIcon1_Click(object sender, EventArgs e)
        {
            if (base.Visible)
            {
                base.Hide();
                return;
            }
            base.Show();
        }
    }
}

Service end fingerprint data to picture:

using System;
using System.Runtime.InteropServices;
using System.IO;

namespace FP_Service
{
    public class BitmapFormat
    {
        public struct BITMAPFILEHEADER
        {
            public ushort bfType;
            public int bfSize;
            public ushort bfReserved1;
            public ushort bfReserved2;
            public int bfOffBits;
        }

        public struct MASK
        {
            public byte redmask;
            public byte greenmask;
            public byte bluemask;
            public byte rgbReserved;
        }

        public struct BITMAPINFOHEADER
        {
            public int biSize;
            public int biWidth;
            public int biHeight;
            public ushort biPlanes;
            public ushort biBitCount;
            public int biCompression;
            public int biSizeImage;
            public int biXPelsPerMeter;
            public int biYPelsPerMeter;
            public int biClrUsed;
            public int biClrImportant;
        }

        /*******************************************
        * Function name: RotatePic       
        * Function function: rotate the picture. The purpose is to save and display the picture in a different direction from the fingerprint     
        * Function input parameter: BmpBuf --- fingerprint string before rotation
        * Function output parameter: ResBuf --- fingerprint string after rotation
        * Function return: None
        *********************************************/
        public static void RotatePic(byte[] BmpBuf, int width, int height, ref byte[] ResBuf)
        {
            int RowLoop = 0;
            int ColLoop = 0;
            int BmpBuflen = width * height;

            try
            {
                for (RowLoop = 0; RowLoop < BmpBuflen; )
                {
                    for (ColLoop = 0; ColLoop < width; ColLoop++)
                    {
                        ResBuf[RowLoop + ColLoop] = BmpBuf[BmpBuflen - RowLoop - width + ColLoop];
                    }

                    RowLoop = RowLoop + width;
                }
            }
            catch (Exception ex)
            {
                //ZKCE.SysException.ZKCELogger logger = new ZKCE.SysException.ZKCELogger(ex);
                //logger.Append();
            }
        }

        /*******************************************
        * Function name: StructToBytes       
        * Function function: convert the structure into an unsigned string array     
        * Function input parameter: StructObj --- converted structure
        *           Size---The size of the transformed structure
        * Function output parameter: None
        * Function returns: array after structure conversion
        *********************************************/
        public static byte[] StructToBytes(object StructObj, int Size)
        {
            int StructSize = Marshal.SizeOf(StructObj);
            byte[] GetBytes = new byte[StructSize];

            try
            {
                IntPtr StructPtr = Marshal.AllocHGlobal(StructSize);
                Marshal.StructureToPtr(StructObj, StructPtr, false);
                Marshal.Copy(StructPtr, GetBytes, 0, StructSize);
                Marshal.FreeHGlobal(StructPtr);

                if (Size == 14)
                {
                    byte[] NewBytes = new byte[Size];
                    int Count = 0;
                    int Loop = 0;

                    for (Loop = 0; Loop < StructSize; Loop++)
                    {
                        if (Loop != 2 && Loop != 3)
                        {
                            NewBytes[Count] = GetBytes[Loop];
                            Count++;
                        }
                    }

                    return NewBytes;
                }
                else
                {
                    return GetBytes;
                }
            }
            catch (Exception ex)
            {
                //ZKCE.SysException.ZKCELogger logger = new ZKCE.SysException.ZKCELogger(ex);
                //logger.Append();

                return GetBytes;
            }
        }

        /*******************************************
        * Function name: GetBitmap       
        * Function function: save the transmitted data as a picture     
        * Function input parameter: buffer --- picture data
        *           nWidth---Width of picture
        *           nHeight---Height of picture
        * Function output parameter: None
        * Function return: None
        *********************************************/
        public static void GetBitmap(byte[] buffer, int nWidth, int nHeight, ref MemoryStream ms)
        {
            int ColorIndex = 0;
            ushort m_nBitCount = 8;
            int m_nColorTableEntries = 256;
            byte[] ResBuf = new byte[nWidth * nHeight*2];

            try
            {
                BITMAPFILEHEADER BmpHeader = new BITMAPFILEHEADER();
                BITMAPINFOHEADER BmpInfoHeader = new BITMAPINFOHEADER();
                MASK[] ColorMask = new MASK[m_nColorTableEntries];

                int w = (((nWidth + 3) / 4) * 4);

                //Picture header information
                BmpInfoHeader.biSize = Marshal.SizeOf(BmpInfoHeader);
                BmpInfoHeader.biWidth = nWidth;
                BmpInfoHeader.biHeight = nHeight;
                BmpInfoHeader.biPlanes = 1;
                BmpInfoHeader.biBitCount = m_nBitCount;
                BmpInfoHeader.biCompression = 0;
                BmpInfoHeader.biSizeImage = 0;
                BmpInfoHeader.biXPelsPerMeter = 0;
                BmpInfoHeader.biYPelsPerMeter = 0;
                BmpInfoHeader.biClrUsed = m_nColorTableEntries;
                BmpInfoHeader.biClrImportant = m_nColorTableEntries;

                //File header information
                BmpHeader.bfType = 0x4D42;
                BmpHeader.bfOffBits = 14 + Marshal.SizeOf(BmpInfoHeader) + BmpInfoHeader.biClrUsed * 4;
                BmpHeader.bfSize = BmpHeader.bfOffBits + ((((w * BmpInfoHeader.biBitCount + 31) / 32) * 4) * BmpInfoHeader.biHeight);
                BmpHeader.bfReserved1 = 0;
                BmpHeader.bfReserved2 = 0;

                ms.Write(StructToBytes(BmpHeader, 14), 0, 14);
                ms.Write(StructToBytes(BmpInfoHeader, Marshal.SizeOf(BmpInfoHeader)), 0, Marshal.SizeOf(BmpInfoHeader));

                //Debug board information
                for (ColorIndex = 0; ColorIndex < m_nColorTableEntries; ColorIndex++)
                {
                   
                    ColorMask[ColorIndex].redmask = (byte)ColorIndex;;
                    ColorMask[ColorIndex].greenmask = (byte)ColorIndex;
                    ColorMask[ColorIndex].bluemask = (byte)ColorIndex;
                    //ColorMask[ColorIndex].greenmask = (byte)ColorIndex;
                    //ColorMask[ColorIndex].bluemask = (byte)ColorIndex;
                    ColorMask[ColorIndex].rgbReserved = 0;

                    ms.Write(StructToBytes(ColorMask[ColorIndex], Marshal.SizeOf(ColorMask[ColorIndex])), 0, Marshal.SizeOf(ColorMask[ColorIndex]));
                }

                //Image rotation to solve the problem of fingerprint image handstand
                RotatePic(buffer, nWidth, nHeight, ref ResBuf);

                byte[] filter = null;
                if (w - nWidth > 0)
                {
                    filter = new byte[w - nWidth];
                }
                for (int i = 0; i < nHeight; i++)
                {
                    ms.Write(ResBuf, i * nWidth, nWidth);
                    if (w - nWidth > 0)
                    {
                        ms.Write(ResBuf, 0, w - nWidth);
                    }
                }
            }
            catch (Exception ex)
            {
               // ZKCE.SysException.ZKCELogger logger = new ZKCE.SysException.ZKCELogger(ex);
               // logger.Append();
            }
        }

        /*******************************************
        * Function name: WriteBitmap       
        * Function function: save the transmitted data as a picture     
        * Function input parameter: buffer --- picture data
        *           nWidth---Width of picture
        *           nHeight---Height of picture
        * Function output parameter: None
        * Function return: None
        *********************************************/
        public static void WriteBitmap(byte[] buffer, int nWidth, int nHeight)
        {
            int ColorIndex = 0;
            ushort m_nBitCount = 8;
            int m_nColorTableEntries = 256;
            byte[] ResBuf = new byte[nWidth * nHeight];

            try
            {

                BITMAPFILEHEADER BmpHeader = new BITMAPFILEHEADER();
                BITMAPINFOHEADER BmpInfoHeader = new BITMAPINFOHEADER();
                MASK[] ColorMask = new MASK[m_nColorTableEntries];
                int w = (((nWidth + 3) / 4) * 4);
                //Picture header information
                BmpInfoHeader.biSize = Marshal.SizeOf(BmpInfoHeader);
                BmpInfoHeader.biWidth = nWidth;
                BmpInfoHeader.biHeight = nHeight;
                BmpInfoHeader.biPlanes = 1;
                BmpInfoHeader.biBitCount = m_nBitCount;
                BmpInfoHeader.biCompression = 0;
                BmpInfoHeader.biSizeImage = 0;
                BmpInfoHeader.biXPelsPerMeter = 0;
                BmpInfoHeader.biYPelsPerMeter = 0;
                BmpInfoHeader.biClrUsed = m_nColorTableEntries;
                BmpInfoHeader.biClrImportant = m_nColorTableEntries;

                //File header information
                BmpHeader.bfType = 0x4D42;
                BmpHeader.bfOffBits = 14 + Marshal.SizeOf(BmpInfoHeader) + BmpInfoHeader.biClrUsed * 4;
                BmpHeader.bfSize = BmpHeader.bfOffBits + ((((w * BmpInfoHeader.biBitCount + 31) / 32) * 4) * BmpInfoHeader.biHeight);
                BmpHeader.bfReserved1 = 0;
                BmpHeader.bfReserved2 = 0;

                Stream FileStream = File.Open("finger.bmp", FileMode.Create, FileAccess.Write);
                BinaryWriter TmpBinaryWriter = new BinaryWriter(FileStream);

                TmpBinaryWriter.Write(StructToBytes(BmpHeader, 14));
                TmpBinaryWriter.Write(StructToBytes(BmpInfoHeader, Marshal.SizeOf(BmpInfoHeader)));

                //Debug board information
                for (ColorIndex = 0; ColorIndex < m_nColorTableEntries; ColorIndex++)
                {
                    ColorMask[ColorIndex].redmask = (byte)ColorIndex;
                    ColorMask[ColorIndex].greenmask = (byte)ColorIndex;
                    ColorMask[ColorIndex].bluemask = (byte)ColorIndex;
                    ColorMask[ColorIndex].rgbReserved = 0;

                    TmpBinaryWriter.Write(StructToBytes(ColorMask[ColorIndex], Marshal.SizeOf(ColorMask[ColorIndex])));
                }

                //Image rotation to solve the problem of fingerprint image handstand
                RotatePic(buffer, nWidth, nHeight, ref ResBuf);

                //Write pictures
                //TmpBinaryWriter.Write(ResBuf);
                byte[] filter = null;
                if (w - nWidth > 0)
                {
                    filter = new byte[w - nWidth];
                }
                for (int i = 0; i < nHeight; i++)
                {
                    TmpBinaryWriter.Write(ResBuf, i * nWidth, nWidth);
                    if (w - nWidth > 0)
                    {
                        TmpBinaryWriter.Write(ResBuf, 0, w - nWidth);
                    }
                }

                FileStream.Close();
                TmpBinaryWriter.Close();
            }
            catch (Exception ex)
            {
                //ZKCE.SysException.ZKCELogger logger = new ZKCE.SysException.ZKCELogger(ex);
                //logger.Append();
            }
        }
    }
}

Client, browser code:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>fp</title>
  <meta name="description" content="fp">

  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">

  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">

  <link rel="stylesheet" href="css/signature-pad.css">
  <script src="/jquery.min.js" type="text/javascript"></script>
</head>
<body onselectstart="return false">


    <div id="signature-pad" class="signature-pad">
        <div>

        </div>
        <div class="signature-pad--body">
            <table width="100%" border="0" cellspacing="0">
                <tr align="center">
                    <td width="100%"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAYAAABIdFAMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHhJREFUeNo8zjsOxCAMBFB/KEAUFFR0Cbng3nQPw68ArZdAlOZppPFIBhH5EAB8b+Tlt9MYQ6i1BuqFaq1CKSVcxZ2Acs6406KUgpt5/LCKuVgz5BDCSb13ZO99ZOdcZGvt4mJjzMVKqcha68iIePB86GAiOv8CDADlIUQBs7MD3wAAAABJRU5ErkJggg==" alt="" width="256" height="288" id="imgDiv" align="middle" /></td>
                </tr>
            </table>
        </div>
      
    </div>
    <script type="text/javascript">
        var ws;
        $(document).ready(function () {

            // test if the browser supports web sockets
            if ("WebSocket" in window) {
                connect("ws://127.0.0.1:8891/");
            } else {
                $('#es').val('the browser does not support this fingerprint! ');
            };

            // function to send data on the web socket
            function ws_send(str) {
                try {
                    ws.send(str);
                } catch (err) {
                    $('#es').val('error');
                }
            }

            // connect to the specified host
            function connect(host) {

                $('#es').val('Connecting to " + host + " ...');
                try {
                    ws = new WebSocket(host); // create the web socket
                } catch (err) {
                    $('#es').val('error');
                }

                ws.onopen = function () {
                   // $('#es').val('device connection succeeded! ');
                };

                ws.onmessage = function (evt) {

                    var obj = evt.data;
                 
                    var img = document.getElementById("imgDiv");
                    img.src = "data:image/png;base64," + obj;

                };

                ws.onclose = function () {
                   // document.getElementById("es").value = "Closed!";
                };
            };

        });

    </script>

</body>
</html>

The above is all the code. After the server runs, it will automatically register the service to the system. It can be started automatically next time. If you don't want to, you can close it in the program. (the data collected by fingerprint identification is black after being transferred to the picture. In fact, it needs red. Here, it is modified from black to red in batch by judging the color paper of picture pixels).

I am a programmer who learns everything to make products. I hope these words can give you some help.

Keywords: ASP.NET C# websocket

Added by agallo on Fri, 14 Jan 2022 16:04:41 +0200