Winform开发中手写签名的实现

简介:

由于项目的需要,需要在项目的Winform系统的一个模块中集成手写签名的功能,一开始对这块不是很了解,只是了解他能够替代鼠标进行签名。既然是签名,一般就是需要记录手稿图片,作为一个记录核实的凭证,因为有效的签名是很难模拟的。市场上也存在很多类型的电子签名笔,一时间还真不知道那种适合。本文主要从签名笔的选型以及功能实现等方面来对实现这个需求进行分析介绍,希望能够给有同样际遇的朋友一个参考。

1、电子手写签名介绍

电子手写签名,其实就是模拟真实的笔进行签名的过程,我这里主要是介绍使用外部设备来记录手稿图片的需求,这样其实就是类似于把我们真实在纸张上的签名内容,放到了电脑记录面板上进行操作了,而这个操作模拟,其实就是利用了类似鼠标功能的接触笔来实现的。

有些笔是在纸上或者电脑屏幕上进行模拟签名,通过一个接收器方式接受笔的接触信号,一般要先设定纸张或者屏幕的范围,然后进行签名书写。如下所示就是这种。

由于签名笔淘宝上也有很多,开始淘到的就是类似这种,不过效果不理想,好像总是定位不准,而且和鼠标发生严重冲突,基本上操作不了,商家客服说很少有这种现象发生,但是却发生在我身上,于是只有退货。然后淘到的是一款汉王手写板笔,开始用的还可以,其实就是代替了鼠标进行操作,试过可以后,就搁置起来。手写板的大概样式类似下图所示。

一直用鼠标模拟签名进行开发,写该篇随笔的时候,本来想用来展示下效果,可惜又用不了,不知道什么原因。

做签名功能开发的时候,其实我是不关注手写笔功能的,因为我想其实如果鼠标能操作就可以,手写笔其实也就应该可以操作。因此只需要在输入的地方记录鼠标操作的痕迹,类似手写签名的效果即可,大概如下所示。

2、手写签名的实现

从上图可以看到,只需要提供一个类似绘图的面板即可记录鼠标的轨迹,也就是功能有点类似Windows自带的白板(或者绘图板)软件即可。

其实要模拟鼠标签名的效果,只需要利用功能强大的GraphicsPath对象就差不多了,剩下的就是记录点和绘制点,设置绘图笔的宽度和颜色等方面。下面我们看看具体的实现代码吧。

首先要申明几个必要的对象,来承载相关的信息。

        //记录直线或者曲线的对象
        private System.Drawing.Drawing2D.GraphicsPath mousePath = new System.Drawing.Drawing2D.GraphicsPath();
        //画笔透明度
        private int myAlpha = 100;
        //画笔颜色对象
        private Color myUserColor = new Color();
        //画笔宽度
        private int myPenWidth = 3;
        //签名的图片对象
        public Bitmap SavedBitmap;

从上图效果图上,我们看到,我们在其中放置了一个绘图面板,其实就是一个PictureBox对象而已,我们只需要在PictureBox对象,记录鼠标的移动、鼠标按下,以及对象刷新操作事件即可实现模拟签名的效果了,如下代码所示。

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                try
                {
                    mousePath.AddLine(e.X, e.Y, e.X, e.Y);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            pictureBox1.Invalidate();
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                mousePath.StartFigure();
            }
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            try
            {
                myUserColor = System.Drawing.Color.Blue;
                myAlpha = 255;
                Pen CurrentPen = new Pen(Color.FromArgb(myAlpha, myUserColor), myPenWidth);
                e.Graphics.DrawPath(CurrentPen, mousePath);
            }
            catch { }
        }

保存及清空操作,其实很简单,清空的时候,记得把绘图面板清空,并重置路径对象即可。保存也是记录PictureBox对象的大小宽度,把图片存储到图片对象里面,供控件使用。

具体实现如下所示。

        private void btnClear_Click(object sender, EventArgs e)
        {
            pictureBox1.CreateGraphics().Clear(Color.White);
            mousePath.Reset();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            SavedBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            pictureBox1.DrawToBitmap(SavedBitmap, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
        }

上面实现还不能完成一个最终的签名效果,有时候,我们需要把这些图片放到数据库里面,如果是把上面的操作的图片记录下来,发现很大,一般我们签名的效果显示,不会很大,一方面只需要辨认其笔迹即可,另外一方面也不会过于增大数据库的存储空间。那么我们就需要对图片大小进行一定的处理了。其实可能在详细信息里面,我们就这样记录显示即可。那么就一定要裁剪图片的大小。

以上的医生签名,我们触发的操作就是弹出一个签名窗体,在其中绘制签名,确认后返回,并把图片进行显示在详细信息窗体里面。

        private void btnDoctorSign_Click(object sender, EventArgs e)
        {
            FrmSignicture dlg = new FrmSignicture();
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.picDoctor.Image = dlg.SavedBitmap;
            }
        }

为了安装最终显示的PictureBox的大小保存图片,我们需要裁减,裁减就是重新根据图片大小进行保存Bitmap对象,这种可以从全屏最初的几M缩小到十几K,方便存储。

至于图片对象存储到数据库,这个由于利用了我Winform开发框架里面的数据库基础对象,基本上不需要特别对待及处理,只需要把图片字段的Byte数组获得即可了。这里就不在赘述Winform开发框架的功能及相关的基类处理了。

        public Bitmap SaveImage(PictureBox pictureBox1)
        {
            Bitmap SavedBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            pictureBox1.DrawToBitmap(SavedBitmap, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));
            return SavedBitmap;
        }

最后,有时候,签名还需要在列表里面显示,这样方便对一些关键信息进行查看核对。如下图所示

那么对于列表中显示图片,我们在DevExpress界面的分页控件中应该如何处理呢,这估计也是DevExpress开发中很多常见问题之一?

其实也很简单,就是在DataSourceChanged 变化的事件中改变单元格的对象属性即可。

                this.winGridViewPager1.OnRefresh += new EventHandler(winGridViewPager1_OnRefresh);
                this.winGridViewPager1.ShowLineNumber = true;
                this.winGridViewPager1.gridView1.Appearance.Row.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
                this.winGridViewPager1.gridView1.Appearance.HeaderPanel.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
                this.winGridViewPager1.AppendedMenu = this.contextMenuStrip1;
                this.winGridViewPager1.gridView1.DataSourceChanged += new EventHandler(gridView1_DataSourceChanged);
                this.winGridViewPager1.gridView1.RowHeight = 44;
        void gridView1_DataSourceChanged(object sender, EventArgs e)
        {
            RepositoryItemPictureEdit pic1 = new RepositoryItemPictureEdit();
            pic1.SizeMode = DevExpress.XtraEditors.Controls.PictureSizeMode.Zoom;
            pic1.NullText = " ";
            pic1.CustomHeight = 44;
            pic1.BestFitWidth = 100;
            this.winGridViewPager1.gridView1.Columns["Signature"].ColumnEdit = picFlight;
            this.winGridViewPager1.gridView1.Columns["Signature"].MaxWidth = 100;
            this.winGridViewPager1.gridView1.Columns["Signature"].MinWidth = 100;

            RepositoryItemPictureEdit picDoctor = new RepositoryItemPictureEdit();
            picDoctor.SizeMode = DevExpress.XtraEditors.Controls.PictureSizeMode.Zoom;
            picDoctor.NullText = " ";
            picDoctor.CustomHeight = 44;
            picDoctor.BestFitWidth = 100;
            this.winGridViewPager1.gridView1.Columns["DoctorSignature"].ColumnEdit = picDoctor;
            this.winGridViewPager1.gridView1.Columns["DoctorSignature"].MaxWidth = 100;
            this.winGridViewPager1.gridView1.Columns["DoctorSignature"].MinWidth = 100;
        }

以上就基本上解决了,签名,以及图片保存,以及列表显示图片效果的问题了。

本文转自博客园伍华聪的博客,原文链接:Winform开发中手写签名的实现,如需转载请自行联系原博主。



目录
相关文章
|
3月前
|
JSON 程序员 API
现在的程序员真是越来越懒了,api 文档都懒得写!程序员:“api工具惯的”
现在的程序员真是越来越懒了,api 文档都懒得写!程序员:“api工具惯的”
|
7月前
|
小程序
uniapp小程序实现横屏手写签名(整理)
uniapp小程序实现横屏手写签名(整理)
|
8月前
|
Web App开发 Java
如何用java实现一个图片验证码
如何用java实现一个图片验证码
36 0
|
8月前
|
存储 前端开发 小程序
小程序封装手写签名组件
本文详细介绍了如何封装一个小程序手写签名组件,包括签名、保存签名、清除签名和撤销功能。我们使用了 canvas 来实现手写签名功能,通过自定义组件的方式来封装手写签名组件,使其可以在不同的页面中重复使用。同时,我们使用了面向对象的编程方式,将手写签名的逻辑封装在一个signaImage类中,使代码更加清晰易懂。最后希望能帮助大家更好地理解和使用本文介绍的手写签名组件。
339 0
|
9月前
|
XML JSON Java
深入探究API接口
API接口作为程序员与外部应用程序交互的桥梁,对于开发工作至关重要。在本文中,我们了解了API接口的定义、类型、使用场景,以及常见的调用方式和相关技术知识。希望本文能够帮助读者更好地掌握和应用API接口,为开发工作带来便利和效率提升。
|
9月前
|
存储 JSON 监控
通俗易懂讲清 API
无论是在科技行业还是其他地方,我遇到很多人对这个相当普遍的术语有着模糊的理解。从技术上讲,API 代表应用程序编程接口,大多数大公司都曾为客户或内部使用构建过 API。但如何用简单的语言来解释 API 呢?除了开发和商业中使用的定义外,是否还有更广泛的含义?首先,让我们退后一步看看网络本身是如何运作的。
81 1
|
设计模式 JavaScript 前端开发
手写简易版的curry
手写简易版的curry
86 0
|
移动开发 小程序 算法
原来Java是这样实现微信小程序加密与解密数据算法的!超赞的有木有?!
微信推出了小程序,很多公司的客户端应用不仅具有了APP、H5、还接入了小程序开发。但是,小程序中竟然没有提供Java版本的加密数据解密算法。这着实让广大的Java开发人员蛋疼。
755 0
原来Java是这样实现微信小程序加密与解密数据算法的!超赞的有木有?!