实现简单的手写涂鸦板(demo源码)
在一些软件系统中,需要用到手写涂鸦的功能,然后可以将涂鸦的结果保存为图片,并可以将“真迹”通过网络发送给对方。这种手写涂鸦功能是如何实现的了?最直接的,我们可以使用Windows提供的GDI技术或GDI+技术来实现绘图功能。但是,要实现一个如此简单的涂鸦板,也不是那么容易的事情。幸运的是,我们可以直接使用OMCS提供的内置集成了这种功能的一个WinForm控件HandwritingPanel。
HandwritingPanel控件的主要接口如下图所示:

/// <summary>
/// 设置画笔颜色。
/// </summary>
Color PenColor {set;}
/// <summary>
/// 设置画笔粗细。
/// </summary>
float PenWidth {set;}
/// <summary>
/// 清空画板。
/// </summary>
void Clear();
/// <summary>
/// 获取涂鸦的结果(位图)。
/// </summary>
Bitmap GetHandWriting();

将HandwritingPanel控件从工具箱拖到你的UI上,可以通过PenColor和PenWidth属性设置画笔的颜色和粗细。运行起来后,就可以在控件的表面进行涂鸦和手写了。
如果需要清空手写板,则调用Clear方法。
当手写结束的时候,则调用GetHandWriting方法得到手写的结果,并保存为位图。位图的大小即是HandwritingPanel控件的尺寸。
OK,下面我们就写了一个使用HandwritingPanel来实现手写涂鸦板的demo,demo的主要代码如下所示:

public partial class HandwritingForm : Form
{
private Color currentColor = Color.Red;
private List<float> penWidthList = new List<float>();
private Bitmap currentImage;
public Bitmap CurrentImage
{
get { return currentImage; }
}
public HandwritingForm()
{
InitializeComponent();
this.handwritingPanel1.PenColor = this.currentColor; //设置画笔颜色
this.penWidthList.Add(2);
this.penWidthList.Add(4);
this.penWidthList.Add(6);
this.penWidthList.Add(8);
this.penWidthList.Add(10);
this.comboBox_brushWidth.DataSource = this.penWidthList;
this.comboBox_brushWidth.SelectedIndex = 1;
}
private void button_color_Click(object sender, EventArgs e)
{
try
{
this.colorDialog1.Color = this.currentColor;
DialogResult result = this.colorDialog1.ShowDialog();
if (result == DialogResult.OK)
{
this.currentColor = this.colorDialog1.Color;
this.handwritingPanel1.PenColor = this.currentColor; //设置画笔颜色
}
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
}
//设置画笔宽度
private void comboBox_brushWidth_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.comboBox_brushWidth.SelectedIndex > 0)
{
this.handwritingPanel1.PenWidth = this.penWidthList[this.comboBox_brushWidth.SelectedIndex];
}
else
{
this.handwritingPanel1.PenWidth = this.penWidthList[0];
}
}
private void Button_clear_Click(object sender, EventArgs e)
{
this.handwritingPanel1.Clear(); //清空手写板
}
private void button_Ok_Click(object sender, EventArgs e)
{
this.currentImage = this.handwritingPanel1.GetHandWriting(); //获取手写图片
this.DialogResult = System.Windows.Forms.DialogResult.OK;
}
private void Button_cancel_Click(object sender, EventArgs e)
{
this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
}
}

其运行效果如下图所示:

实现简单的手写涂鸦板(demo源码)的更多相关文章
- javaScript(js)手写原生任务定时器源码
javaScript(js)手写原生任务定时器 功能介绍 定时器顾名思义就是在某个特定的时间去执行一些任务,现代的应用程序早已不是以前的那些由简单的增删改查拼凑而成的程序了,高复杂性早已是标配,而任务 ...
- OpenCV+TensorFlow图片手写数字识别(附源码)
初次接触TensorFlow,而手写数字训练识别是其最基本的入门教程,网上关于训练的教程很多,但是模型的测试大多都是官方提供的一些素材,能不能自己随便写一串数字让机器识别出来呢?纸上得来终觉浅,带着这 ...
- Spring学习之——手写Mini版Spring源码
前言 Sping的生态圈已经非常大了,很多时候对Spring的理解都是在会用的阶段,想要理解其设计思想却无从下手.前些天看了某某学院的关于Spring学习的相关视频,有几篇讲到手写Spring源码,感 ...
- 6 手写Java LinkedHashMap 核心源码
概述 LinkedHashMap是Java中常用的数据结构之一,安卓中的LruCache缓存,底层使用的就是LinkedHashMap,LRU(Least Recently Used)算法,即最近最少 ...
- 3 手写Java HashMap核心源码
手写Java HashMap核心源码 上一章手写LinkedList核心源码,本章我们来手写Java HashMap的核心源码. 我们来先了解一下HashMap的原理.HashMap 字面意思 has ...
- 2 手写Java LinkedList核心源码
上一章我们手写了ArrayList的核心源码,ArrayList底层是用了一个数组来保存数据,数组保存数据的优点就是查找效率高,但是删除效率特别低,最坏的情况下需要移动所有的元素.在查找需求比较重要的 ...
- 1 手写Java ArrayList核心源码
手写ArrayList核心源码 ArrayList是Java中常用的数据结构,不光有ArrayList,还有LinkedList,HashMap,LinkedHashMap,HashSet,Queue ...
- [c#]asp.net开发微信公众平台(7)前6篇的整体框架demo源码
这里给出的demo是具备整体框架的微信公众平台源码, 所谓demo就是拿过去就可以直接演示使用的东西, 当然不会具备非常详细的具体到业务层面.数据层面的东西, 每个人都可以在此基础上自由发挥, 只 ...
- 近期热门微信小程序demo源码下载汇总
近期微信小程序demo源码下载汇总,乃小程序学习分析必备素材!点击标题即可下载: 即速应用首发!原创!电商商场Demo 优质微信小程序推荐 -秀人美女图 图片下载.滑动翻页 微信小程序 - 新词 GE ...
随机推荐
- react重学
知识点一:react解析中 return {__html:rawMarkup}; 这里的html前边用的是双下划线(谢谢学妹的指点)
- Python tools used for file name devision
今天因为工作的缘故,需要用Python写一个能够完全分解文件名的小程序. import os #path = os.path.abspath('.') def split_fully(name): p ...
- AppCan 双击返回按钮退出应用
使用AppCan开发手机应用,拦截返回键实现自定义2秒内双击退出应用的操作 var c1c = 0; window.uexOnload = function(type){ uexWindow.setR ...
- [HMLY]6.iOS Xcode全面剖析
一.创建一个新工程 1.第一步打开Xcode,找到Xcode程序图标并点击 2.如下界面,我们点击新建一个项目,即第二项 (1).Get started with a playground playg ...
- 如何在MyEclipse中配置jre的编译运行环境
由于在MyEclipse中已经自带了jre编译环境,但由于版本太低,所以有时候需要将编译环境配置为系统的jre版本.在MyEclipse中配置jre的编译运行环境很简单,只需要全局配置一次,则所有项目 ...
- [SOJ] shortest path in unweighted graph
Description 输入一个无向图,指定一个顶点s开始bfs遍历,求出s到图中每个点的最短距离. 如果不存在s到t的路径,则记s到t的距离为-1. Input 输入的第一行包含两个整数n和m, ...
- DrawerLayout,ToolBar 和 TabHost 的使用
ActionBar 定义起来不方便 toolbar: 最重要的特性,显示menu菜单,右上角三个点的菜单按钮,使用灵活 使用:1,布局文件,包裹LinearLayout 放imageView, 或者I ...
- Struts2的DMI跟SMI
我使用的Struts2的版本是2.5.2,今天在使用Struts2的DMI(动态方法调用)的时候出现了一个有趣的问题,我先把我的配置及代码展示一下: web.xml <filter> &l ...
- 【转】Zookeeper-Watcher机制与异步调用原理
声明:本文转载自http://shift-alt-ctrl.iteye.com/blog/1847320,转载请务必声明. Watcher机制:目的是为ZK客户端操作提供一种类似于异步获得数据的操作. ...
- Python数据预处理—归一化,标准化,正则化
关于数据预处理的几个概念 归一化 (Normalization): 属性缩放到一个指定的最大和最小值(通常是1-0)之间,这可以通过preprocessing.MinMaxScaler类实现. 常用的 ...