欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C# WinForm實現(xiàn)畫筆簽名功能

 更新時間:2024年11月19日 16:16:35   作者:初九之潛龍勿用  
這篇文章主要為大家詳細介紹了如何通過 C# WinForm 通過畫布畫筆實現(xiàn)手寫簽名,并在開發(fā)過程中解決遇到的一些格式轉(zhuǎn)換的問題簽名功能,希望對大家有所幫助

需求

我的文章 《C# 結(jié)合JavaScript實現(xiàn)手寫板簽名并上傳到服務(wù)器》主要介紹了 web 版的需求實現(xiàn),本文應(yīng)項目需求介紹如何通過 C# WinForm 通過畫布畫筆實現(xiàn)手寫簽名,并在開發(fā)過程中解決遇到的一些格式轉(zhuǎn)換的問題,提供一些思路。

實現(xiàn)效果

簽名功能的顯示界面如下圖:

該效果主要實現(xiàn)如下功能:

1、提供畫布,設(shè)計畫筆類,實現(xiàn)畫筆簽名

2、點擊重簽按鈕清空畫布

3、點擊確認(rèn)按鈕保存畫布位圖到指定的格式(提供三種保存類型,文件,二進制數(shù)據(jù)和BASE64編碼)

開發(fā)運行環(huán)境

操作系統(tǒng): Windows Server 2019 DataCenter

手寫觸屏設(shè)備:Microsoft Surface Pro 9

.net版本: .netFramework4.0 或以上

開發(fā)工具:VS2019  C#

設(shè)計實現(xiàn)

界面布局

主要在WinForm上放置如下控件,Name 為 canvasPanel 的 System.Windows.Forms.Panel控件,一些Label控件、radioButton控件和兩個功能按鈕Button控件,如下圖:

初始化

Form1 初始化如下變量: 

      bool isMouseDown = false;      // 判斷鼠標(biāo)或手指是否按下,按下為 true
      Graphics canvas = null;    // 定義繪圖畫布
      Image bmpData = null;     // 定義 Image 圖像,將來導(dǎo)出時使用

實例化變量的過程中 new Bitmap ,則產(chǎn)生的默認(rèn)格式為 System.Drawing.Imaging.ImageFormat.MemoryBmp 格式,這會產(chǎn)生一個問題,保存的位圖是全黑色。因此一個解決的思路是先臨時創(chuàng)建一個白色背景的JPEG圖片,圖片的大小取決于panel控件的寬度和高度,然后再將畫布的圖像 bmpData 變量,實例化創(chuàng)建引用這個臨時圖片的路徑。

示例代碼如下:

public partial class Form1 : Form
    {
        bool isMouseDown = false;
        Graphics canvas = null;
        Image bmpData = null;
        public Form1()
        {
            InitializeComponent();
            
            canvas = canvasPanel.CreateGraphics();
            string tmpJpg = Application.StartupPath + "\\tmpimg\\" + System.Guid.NewGuid().ToString() + ".jpg";
            using (Bitmap bitmap = new Bitmap(canvasPanel.Width, canvasPanel.Height))
            {
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    graphics.Clear(Color.White);
                }
                bitmap.Save(tmpJpg, ImageFormat.Jpeg);
            }
            bmpData = new Bitmap(tmpJpg);
            
            
            
        }
 
 
}

畫筆繪圖

Graphics canvas 為canvasPanel控件創(chuàng)建的畫布,首先定義實現(xiàn)一個畫筆類,代碼如下:

        public static class signPen
        {
            public static Point LastPoint { get; set; }
            public static Color Color { get; set; }
            public static int Width { get; set; }
            static signPen()
            {
                Color = Color.Black;
                Width = 2;
            }
        }

畫筆類主要包括 :

序號屬性名類型說明
1LastPointPoint記錄最后一次畫筆的坐標(biāo)點,并結(jié)合 DrawLine 方法畫出想要的線段
2ColorColor畫筆的顏色,默認(rèn)為黑色
3Widthint畫筆的粗線,默認(rèn)為2,1為最細

實現(xiàn)繪圖,主要是通過畫筆類,在canvasPanel 的鼠標(biāo)按下、鼠標(biāo)移動、和鼠標(biāo)抬起事件定義相關(guān)操作。

序號事件名說明
1canvasPanel_MouseDown記住鼠標(biāo)是否按下,將 bool isMouseDown 置為true,另一個關(guān)鍵功能是將按下的點(Point),賦值到畫筆的 LastPoint 屬性,以備后續(xù)繪制線條使用
2CanvasPanel_MouseMove判斷 isMouseDown 標(biāo)志,如果為 true 則引入畫布圖像,從最后一次的Point結(jié)合當(dāng)前鼠標(biāo)的Point 進行 DrawLine 操作,并形成新的位圖數(shù)據(jù)
3CanvasPanel_MouseUp將 bool isMouseDown 置為 false,不再進行繪制

示例代碼如下:

        private void canvasPanel_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isMouseDown = true;
                signPen.LastPoint = new Point(e.X, e.Y);
            }
        }
 
        private void CanvasPanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMouseDown == true)
            {
                Graphics gf = Graphics.FromImage(bmpData);
           
            //設(shè)置高質(zhì)量插值法
            gf.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            //設(shè)置高質(zhì)量,低速度呈現(xiàn)平滑程度 
            gf.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            Pen pen = new Pen(signPen.Color, signPen.Width);
            Point curPoint = new Point(e.X, e.Y);
 
                gf.DrawLine(pen, signPen.LastPoint, curPoint);
                signPen.LastPoint = curPoint;
                canvas.DrawImage(bmpData, 0,0);
 
            }
        }
 
        private void CanvasPanel_MouseUp(object sender, MouseEventArgs e)
        {
            isMouseDown = false;
        }

清空畫布

可通過點擊“重簽” 按鈕,清空畫布,實現(xiàn)如初始化功能,代碼如下:

            string tmpJpg = Application.StartupPath + "\\tmpimg\\" + System.Guid.NewGuid().ToString() + ".jpg";
            using (Bitmap bitmap = new Bitmap(canvasPanel.Width, canvasPanel.Height))
            {
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    graphics.Clear(Color.White);
                }
                bitmap.Save(tmpJpg, ImageFormat.Jpeg);
            }
 
            bmpData = new Bitmap(tmpJpg);
            canvas.DrawImage(bmpData, 0,0);

導(dǎo)出位圖數(shù)據(jù)

繪制完成,我們就需要將 bmpData  位圖變量數(shù)據(jù)導(dǎo)出我們想要的格式,為了便于演示,我們設(shè)置了一組 radioButton 選項,可以導(dǎo)出三種類型的形式數(shù)據(jù),如下表:

序號事件名說明
1radioButton1直接導(dǎo)出成文件(jpeg類型)
2radioButton2導(dǎo)出二進制數(shù)據(jù) (byte[])
3radioButton3導(dǎo)出 base64 數(shù)據(jù) (string類型)

假設(shè)“確定”按鈕 Name 為 “Button13”,并假設(shè)輸出到D盤根目錄下,示例代碼如下:

        private void Button13_Click(object sender, EventArgs e)
        {
            
 
            string jpgFilename = "d:\\" + System.Guid.NewGuid().ToString() + ".jpg";
 
 
            bmpData.Save(jpgFilename,ImageFormat.Jpeg);
 
            if (File.Exists(jpgFilename) == false)
            {
                MessageBox.Show(string.Format("保存文件至{0}失敗。", jpgFilename));
                return;
            }
            if (radioButton1.Checked == true)
            {
                MessageBox.Show(string.Format("已成功保存至{0}。", jpgFilename));
            }
            if (radioButton2.Checked == true)
            {
                
                byte[] bytes2=fe.GetBinaryData(jpgFilename);
                MessageBox.Show(string.Format("已成功保存為二進制數(shù)據(jù),長度{0}。", bytes2.Length));
            }
            if (radioButton3.Checked == true)
            {
                string base64str = ImgToBase64String(jpgFilename, false);
                MessageBox.Show(string.Format("已成功保存為BASE64,長度{0}。", base64str.Length));
            }
 
        }
 
public byte[] GetBinaryData(string filename)
        {
            if(!File.Exists(filename))
            {
                return null;
            }
            try
            {
                FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
                byte[] imageData = new Byte[fs.Length];
                fs.Read( imageData, 0,Convert.ToInt32(fs.Length));
                fs.Close();
                return imageData;
            }
            catch(Exception)
            {
                return null;
            }
            finally
            {
                
            }
        }        
 
        public string ImgToBase64String(string Imagefilename, bool outFullString = false)
        {
            try
            {
                System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(Imagefilename);
 
                MemoryStream ms = new MemoryStream();
                //            bmp.Save(ms,ImageFormat.Jpeg)
                System.Drawing.Imaging.ImageFormat iformat = System.Drawing.Imaging.ImageFormat.Jpeg;
                string extension = System.IO.Path.GetExtension(Imagefilename).Replace(".", "").ToLower();
                if (extension == "bmp")
                {
                    iformat = System.Drawing.Imaging.ImageFormat.Bmp;
                }
                else if (extension == "emf")
                {
                    iformat = System.Drawing.Imaging.ImageFormat.Emf;
                }
                else if (extension == "exif")
                {
                    iformat = System.Drawing.Imaging.ImageFormat.Exif;
                }
                else if (extension == "gif")
                {
                    iformat = System.Drawing.Imaging.ImageFormat.Gif;
                }
                else if (extension == "icon")
                {
                    iformat = System.Drawing.Imaging.ImageFormat.Icon;
                }
                else if (extension == "png")
                {
                    iformat = System.Drawing.Imaging.ImageFormat.Png;
                }
                else if (extension == "tiff")
                {
                    iformat = System.Drawing.Imaging.ImageFormat.Tiff;
                }
                else if (extension == "wmf")
                {
                    iformat = System.Drawing.Imaging.ImageFormat.Wmf;
                }
 
                bmp.Save(ms, iformat);
                byte[] arr = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length);
                ms.Close();
                bmp.Dispose();
                string rv = Convert.ToBase64String(arr);
                if (outFullString == true)
                {
                    rv = "data:image/" + extension + ";base64," + rv;
                }
                return rv;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

小結(jié)

對于 new Bitmap 創(chuàng)建的位圖,我們還可以使用 Png 格式,以防止“黑圖”的出現(xiàn),我們在應(yīng)用中可以靈活掌握,如下代碼:

    Bitmap newimg = new Bitmap(100,100);
    newimg.Save("d:\\test.jpg", System.Drawing.Imaging.ImageFormat.Png);

保存的數(shù)據(jù),顯示在畫布上可采取如下方法:

1、文件型

            System.Drawing.Image img2 = new Bitmap(你的文件地址);
 
                canvas.DrawImage(img2, 0, 0);
                MessageBox.Show("顯示文件到畫布成功!");

2、二進制型

                byte[] bytes = 你的二進制數(shù)據(jù);
                MemoryStream ms = new MemoryStream(bytes);
                System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
                canvas.DrawImage(img, 0, 0);
                MessageBox.Show("顯示二進制到畫布成功!");

3、base64型

string base64 = 你的base64數(shù)據(jù);
                byte[] arr = Convert.FromBase64String(base64);
                MemoryStream ms2 = new MemoryStream(arr);
                System.Drawing.Image img2 = System.Drawing.Image.FromStream(ms2);
                canvas.DrawImage(img2, 0, 0);
                MessageBox.Show("顯示base64到畫布成功!");

以上就是C# WinForm實現(xiàn)畫筆簽名功能的詳細內(nèi)容,更多關(guān)于C#畫筆簽名的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 圖解如何使用C#創(chuàng)建Windows服務(wù)

    圖解如何使用C#創(chuàng)建Windows服務(wù)

    本文主要介紹了圖解如何使用C#創(chuàng)建Windows服務(wù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • c#遠程html數(shù)據(jù)抓取實例分享

    c#遠程html數(shù)據(jù)抓取實例分享

    這篇文章主要介紹了c#遠程html數(shù)據(jù)抓取的方法,大家參考使用吧
    2013-12-12
  • C#中載入界面的常用方法

    C#中載入界面的常用方法

    這篇文章主要介紹了C#中載入界面的常用方法,涉及窗體的操作,非常具有實用價值,需要的朋友可以參考下
    2014-10-10
  • 基于C#實現(xiàn)屏幕桌面截圖

    基于C#實現(xiàn)屏幕桌面截圖

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)屏幕桌面截圖以及左上角區(qū)域截圖功能,文中的示例代碼講解詳細,對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以了解一下
    2022-12-12
  • 基于C#實現(xiàn)簡單的隨機抽獎小程序

    基于C#實現(xiàn)簡單的隨機抽獎小程序

    臨近春節(jié),大街小巷的地方都有抽獎活動,那么基于C#是如何實現(xiàn)簡單的抽獎程序的呢,下面小編給大家分享了具體代碼,有需要的朋友參考下
    2016-01-01
  • C#操作 JSON方法匯總

    C#操作 JSON方法匯總

    本文給大家匯總了一下使用C#操作Json的方法,非常的簡單實用,有需要的小伙伴可以參考下
    2015-10-10
  • 基于C#實現(xiàn)FTP下載文件

    基于C#實現(xiàn)FTP下載文件

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)FTP下載文件,文中的示例代碼講解詳細,對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12
  • C#使用DateTime.Now靜態(tài)屬性動態(tài)獲得系統(tǒng)當(dāng)前日期和時間

    C#使用DateTime.Now靜態(tài)屬性動態(tài)獲得系統(tǒng)當(dāng)前日期和時間

    本文主要介紹了C#使用DateTime.Now靜態(tài)屬性動態(tài)獲得系統(tǒng)當(dāng)前日期和時間,DateTime結(jié)構(gòu)的Now靜態(tài)屬性只是得到一個系統(tǒng)時間對象,該時間對象不會隨著系統(tǒng)時間的變化而變化,如果要動態(tài)顯示系統(tǒng)時間,可以使用計時器間隔地獲取系統(tǒng)時間對象并顯示,感興趣的可以了解一下
    2024-01-01
  • C# 實現(xiàn)與現(xiàn)有.NET事件橋接簡單實例

    C# 實現(xiàn)與現(xiàn)有.NET事件橋接簡單實例

    這篇文章主要介紹了C# 實現(xiàn)與現(xiàn)有.NET事件橋接簡單實例的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • C#如何打開并讀取usb的文件目錄

    C#如何打開并讀取usb的文件目錄

    這篇文章主要介紹了用C#語言實現(xiàn)打開并讀取usb的文件目錄,但是實現(xiàn)此功能要注意一點必須在u盤插入才能接受到信息,需要的朋友可以參考下
    2015-07-07

最新評論