广告位联系
返回顶部
分享到

C# WinForm实现画笔签名功能介绍

C#教程 来源:互联网 作者:佚名 发布时间:2024-11-20 08:18:10 人浏览
摘要

实现效果 签名功能的显示界面如下图: 该效果主要实现如下功能: 1、提供画布,设计画笔类,实现画笔签名 2、点击重签按钮清空画布 3、点击确认按钮保存画布位图到指定的格式(提供三种

实现效果

签名功能的显示界面如下图:

该效果主要实现如下功能:

1、提供画布,设计画笔类,实现画笔签名

2、点击重签按钮清空画布

3、点击确认按钮保存画布位图到指定的格式(提供三种保存类型,文件,二进制数据和BASE64编码)

开发运行环境

操作系统: Windows Server 2019 DataCenter

手写触屏设备:Microsoft Surface Pro 9

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

开发工具:VS2019  C#

设计实现

界面布局

主要在WinForm上放置如下控件,Name 为 canvasPanel 的 System.Windows.Forms.Panel控件,一些Label控件、radioButton控件和两个功能按钮Button控件,如下图:

初始化

Form1 初始化如下变量: 

1

2

3

bool isMouseDown = false;      // 判断鼠标或手指是否按下,按下为 true

Graphics canvas = null;    // 定义绘图画布

Image bmpData = null;     // 定义 Image 图像,将来导出时使用

实例化变量的过程中 new Bitmap ,则产生的默认格式为 System.Drawing.Imaging.ImageFormat.MemoryBmp 格式,这会产生一个问题,保存的位图是全黑色。因此一个解决的思路是先临时创建一个白色背景的JPEG图片,图片的大小取决于panel控件的宽度和高度,然后再将画布的图像 bmpData 变量,实例化创建引用这个临时图片的路径。

示例代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

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控件创建的画布,首先定义实现一个画笔类,代码如下:

1

2

3

4

5

6

7

8

9

10

11

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;

    }

}

画笔类主要包括 :

序号 属性名 类型 说明
1 LastPoint Point 记录最后一次画笔的坐标点,并结合 DrawLine 方法画出想要的线段
2 Color Color 画笔的颜色,默认为黑色
3 Width int 画笔的粗线,默认为2,1为最细

实现绘图,主要是通过画笔类,在canvasPanel 的鼠标按下、鼠标移动、和鼠标抬起事件定义相关操作。

序号 事件名 说明
1 canvasPanel_MouseDown 记住鼠标是否按下,将 bool isMouseDown 置为true,另一个关键功能是将按下的点(Point),赋值到画笔的 LastPoint 属性,以备后续绘制线条使用
2 CanvasPanel_MouseMove 判断 isMouseDown 标志,如果为 true 则引入画布图像,从最后一次的Point结合当前鼠标的Point 进行 DrawLine 操作,并形成新的位图数据
3 CanvasPanel_MouseUp 将 bool isMouseDown 置为 false,不再进行绘制

示例代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

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

    

    //设置高质量插值法

    gf.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

    //设置高质量,低速度呈现平滑程度

    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;

}

清空画布

可通过点击“重签” 按钮,清空画布,实现如初始化功能,代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

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

导出位图数据

绘制完成,我们就需要将 bmpData  位图变量数据导出我们想要的格式,为了便于演示,我们设置了一组 radioButton 选项,可以导出三种类型的形式数据,如下表:

序号 事件名 说明
1 radioButton1 直接导出成文件(jpeg类型)
2 radioButton2 导出二进制数据 (byte[])
3 radioButton3 导出 base64 数据 (string类型)

假设“确定”按钮 Name 为 “Button13”,并假设输出到D盘根目录下,示例代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

        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("已成功保存为二进制数据,长度{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;

            }

        }

小结

对于 new Bitmap 创建的位图,我们还可以使用 Png 格式,以防止“黑图”的出现,我们在应用中可以灵活掌握,如下代码:

1

2

Bitmap newimg = new Bitmap(100,100);

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

保存的数据,显示在画布上可采取如下方法:

1、文件型

1

2

3

4

System.Drawing.Image img2 = new Bitmap(你的文件地址);

 

    canvas.DrawImage(img2, 0, 0);

    MessageBox.Show("显示文件到画布成功!");

2、二进制型

1

2

3

4

5

byte[] bytes = 你的二进制数据;

MemoryStream ms = new MemoryStream(bytes);

System.Drawing.Image img = System.Drawing.Image.FromStream(ms);

canvas.DrawImage(img, 0, 0);

MessageBox.Show("显示二进制到画布成功!");

3、base64型

1

2

3

4

5

6

string base64 = 你的base64数据;

                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到画布成功!");


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • C#中SetStyle的具体使用介绍
    在C#的Windows Forms应用程序中,SetStyle方法是Control类的一个成员,用于启用或禁用特定的控件样式。这些样式控制控件的不同行为和外观。以
  • C# WinForm实现画笔签名功能介绍

    C# WinForm实现画笔签名功能介绍
    实现效果 签名功能的显示界面如下图: 该效果主要实现如下功能: 1、提供画布,设计画笔类,实现画笔签名 2、点击重签按钮清空画布
  • C#文字识别API场景解析、表格识别提取功能实现
    在快节奏的工作与生活环境中,如何提高企业工作效率、提升用户体验成为了人们追求的共同目标。针对市场发展需求,一种将任意场景图
  • c#线性回归和多项式拟合示例详解
    1. 线性回归 公式:线性回归的目标是拟合一条直线,形式为: y=mx+by=mx+b 其中: yy是因变量(目标值) xx是自变量(特征值) mm是斜率(s
  • C#删除Word文档中的段落的方法

    C#删除Word文档中的段落的方法
    免费.NET Word 库 -Free Spire.Doc for .NET。该库支持实现创建、编辑、转换Word文档等多种操作,可以直接在Visual Studio中通过NuGet搜索 FreeSpire.Doc,然
  • c#强制类型转换int方式
    c#强制类型转换int 在 C# 中有三种方法把其它类型转为整型,分别是 : int.Parse() 强制转换(int) Convert.ToInt32() 下面探讨它们各自的特点及效率
  • C#生成exe可执行文件的常用方法

    C#生成exe可执行文件的常用方法
    生成可执行文件的方法常用的有2种设置 一、常用2种方法 1、生成菜单 2、项目文件夹下的可执行文件 3、项目菜单---S71500Comm属性
  • 使用C#快速搭建一个在windows运行的exe应用

    使用C#快速搭建一个在windows运行的exe应用
    这是一个比较旧的内容,但是一直都没有空写,今天花点时间,把我掌握的C# 分享给初学的人或者感兴趣的人,希望能对你有一定帮助 1.1
  • C# SqlSugar批量执行SQL语句及批量更新实体对象的操
    SqlSugar简介 SqlSugar 是一款 老牌 .NET 开源多库架构ORM框架(EF Core单库架构),由果糖大数据科技团队 维护和更新 ,开箱即用最易上手的.NE
  • C#类型转换之显式和隐式转换介绍
    在C#编程中,类型转换是一个核心概念,它允许我们在程序中处理不同类型的数据。类型转换可以分为两大类:显式类型转换(Explicit Casti
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计