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;
        }

以上就基本上解決了,簽名,以及圖片保存,以及列表顯示圖片效果的問題了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM