在移动或Web应用中实现用户签名捕获功能,最初对此持怀疑态度,不确定这是否是一项易于实现且易于使用的功能。
开始与好友Google进行头脑风暴,并搜索了一些可能的术语,找到了正确的方向。第一个想法是使用第三方组件,如ActiveX等,安装在客户端以帮助捕获输入。这是不惜一切代价想要避免的。考虑到有如此多不同的设备、操作系统和浏览器,这完全没有意义,而且会招致麻烦。
另一个提示是使用HTML5Canvas提供的功能。Canvas是HTML5的一部分,允许动态、可脚本化的2D形状和位图图像渲染。它是一个低级别的、过程化的模型,更新位图,并且没有内置的场景图。
因此,走在了正确的道路上。使用Canvas,并以某种方式将此签名保存在服务器端以供进一步使用。如果正在存储用户的签名,可能需要考虑是否真的有必要以及与之相关的隐私问题和措施。
捕获用户输入是在使用Canvas时最常见的场景之一。Canvas是当今HTML5中对游戏开发者最强大的元素。
由于不想为捕获签名输入(实际上只是用户驱动的绘图)重新发明轮子,决定使用Szymon Nowak编写的Signature Pad。用他的话来说,Signature Pad是一个用于绘制平滑签名的JavaScript库。它基于HTML5Canvas,并使用基于平滑签名的可变宽度贝塞尔曲线插值。它在所有现代桌面和移动浏览器中工作,并且不依赖于任何外部库。
创建的一个非常基础的HTML页面看起来像这样,包含几个按钮和一个用于捕获用户签名的Canvas。
<div class="page-header">
<h1>使用SignaturePad和Web API演示签名应用</h1>
</div>
<div class="panel panel-default">
<div class="panel-body" id="signature-pad">
<div></div>
<div>
<div class="alert alert-info">
请在上面签名
</div>
<button class="btn btn-info" data-action="clear">
清除
</button>
<button class="btn btn-success" data-action="save">
保存
</button>
</div>
</div>
</div>
接下来是将Canvas上的捕获签名保存到服务器。事实证明,Canvas超出了想象。它提供了一个叫做toDataURL()的方法。
它基本上是一个包含以指定格式(默认为PNG)表示的图像的URL。返回的图像是96dpi。要获取Canvas的图像数据URL,可以使用Canvas对象的toDataURL()方法,该方法将Canvas绘制转换为64位编码的PNG URL。如果希望图像数据URL是jpeg格式,可以将image/jpeg作为toDataURL()方法的第一个参数传递。如果希望控制jpeg图像的质量,可以将0到1之间的数字作为第二个参数传递给toDataURL()方法。
太棒了,不是吗?
Web API用于在服务器上保存图像
决定亲自尝试Web API来实现服务器端保存,因为之前没有尝试过。首先,服务器端Web API是定义的请求-响应消息系统的程序化接口,通常以JSON或XML表示,并通过Web公开——最常见的是通过基于HTTP的Web服务器。
首先在Visual Studio 2013中创建了一个新的ASP.NET项目,并选择了带有Web API的Empty Project模板。
项目创建后,下一步是添加一个新的控制器并将其重命名为SignatureController。控制器看起来像这样:
public class SignatureController : ApiController
{
public IHttpActionResult Post([FromBody]Signature data)
{
byte[] photo = Convert.FromBase64String(data.Value);
var dir = new DirectoryInfo(HostingEnvironment.ApplicationPhysicalPath);
using (System.IO.FileStream fs = System.IO.File.Create(Path.Combine
(dir.FullName,
string.Format("Img_{0}.png", Guid.NewGuid()))))
{
fs.Write(photo, 0, photo.Length);
}
return Ok();
}
}
控制器以Signature模型作为输入。然而,这个示例只定义了签名的dataUrl或值,但可以考虑扩展其他成员,例如,用户的名字。
现在,让回到最初创建的HTML页面,开始使用SignaturePad,并扩展为jQuery调用以访问Web API。
dataURL = signaturePad.toDataURL().replace('data:image/png;base64,', '');
var data = JSON.stringify({
value: dataURL
});
$.ajax({
type: "POST",
url: "/api/signature",
contentType: false,
processData: false,
data: data,
contentType: "application/json; charset=utf-8",
success: function(msg) {
alert("Done!");
},
error: onWebServiceFailed
});
就是这样。这是一个完整的最小解决方案,用于捕获用户输入直到将其作为文件保存在服务器上。
Web技术的最新发展为开发者以更简单的方式实现功能打开了机会。重要的是要跟上这些技术的步伐,相信,这是具有挑战性的部分(尤其是对来说)。