当前位置: 代码网 > it编程>编程语言>C# > C#结合JavaScript实现手写板签名效果

C#结合JavaScript实现手写板签名效果

2024年05月26日 C# 我要评论
应用场景我们最近开发了一款笔迹测试功能的程序(测试版),用户在手写板上手写签名,提交后即可测试出被测试者的心理素质评价分析。类似功能的场景还比如,在银行柜台 办理业务,期间可能需要您使用手写设备进行签

应用场景

我们最近开发了一款笔迹测试功能的程序(测试版),用户在手写板上手写签名,提交后即可测试出被测试者的心理素质评价分析。类似功能的场景还比如,在银行柜台 办理业务,期间可能需要您使用手写设备进行签名并确认;保险续期小程序,到期后需要你在确认续期条款后,在手机上提供的签名区域进行签名并提交确认。

实现效果

笔迹测试显示界面如下:

可选择画笔颜色(默认为黑色笔) ,在虚线框内可随便写一段文字,点击提交即可。当然程序还提供拍照上传功能,这里不再详述。下面我们开始介绍,c#如何结合javascript实现手写板写字并上传到服务器进行处理。

开发运行环境

操作系统: windows server 2019 datacenter

手写触屏设备:microsoft surface pro 9

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

开发工具:vs2019  c#

设计实现

手写功能

设计采用了 iframe 嵌入式的方式实现 javascript 前端,假设页面为 hw.aspx ,该页面实现了手写功能、重写功能、画笔选择功能和提交功能,其完整示例代码如下:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=yes"/>
    <title>手写板</title>
    <style type="text/css">
        html,body{
            margin: 0;
            padding: 0;
        }
        .saveimg{
            text-align: center;
        }
        .saveimgs span{
            display: inline-block;
            margin-top:5px;
        }
    </style>
</head>
<body>
 <script src="jquery-3.3.1.min.js"></script>
 
<div align="center">
    <canvas id="mycanvas" width="500" height="300" style="border:1px dotted #6699cc"></canvas>
    <div class="control-ops control">
        <button type="button" class="btn btn-primary" onclick="javascript:cleararea();return false;">重写</button>
        <select style="display:none" id="selwidth" onchange="aaa()">
        <option value="1">1</option>
        <option value="3" selected="selected">3</option>
        <option value="5">5</option>
        <option value="7">7</option>
        <option value="9">9</option>
        <option value="11">11</option>
    </select>
        <select id="selcolor" onchange="aaa2()">
        <option value="black" selected="selected">黑色笔</option>
        <option value="blue">蓝色笔</option>
        <option value="red">红色笔</option>
        <option value="green">绿色笔</option>
        <option value="yellow">黄色笔</option>
        <option value="gray">深灰笔</option>
    </select>
        <button type="button" class="saveimg" onclick="javascript:saveimageinfo();return false;">提交</button>
    </div>
    <div class="saveimgs"></div>
</div>
 
</body>
 
<script type="text/javascript">
    var mousepressed = false;
    var lastx, lasty;
    var ctx = document.getelementbyid('mycanvas').getcontext("2d");
    var c = document.getelementbyid("mycanvas");
    var control = document.getelementsbyclassname("control")[0];
    var saveimgs = document.getelementsbyclassname("saveimgs")[0];
 
    window.onload = function () {
        document.getelementbyid('mycanvas').setattribute("width", $(window).width()-5);
        initthis();
    }
 
    function saveimageinfo(){
        var image = c.todataurl("image/png");
        window.parent.document.getelementbyid('pbase64').value = image;
        window.parent.document.getelementbyid('phw').click();
 
        return;
        var ctximg = document.createelement("span");
        ctximg.innerhtml = "<img src='"+image+"' alt='from canvas'/>";
        if(saveimgs.getelementsbytagname('span').length >= 1){
            var span_old = saveimgs.getelementsbytagname("span")[0];
            saveimgs.replacechild(ctximg,span_old)
        }
        else{
            saveimgs.appendchild(ctximg);
        }
    }
 
 
    var selected1,selected2;
    function aaa(){
        var sel = document.getelementbyid('selwidth');
        var value = sel.selectedindex;
        return selected1 = sel[value].value;
    }
    function aaa2(){
        var sel2 = document.getelementbyid('selcolor');
        var value = sel2.selectedindex;
        return selected2 = sel2[value].value;
    }
 
    function initthis() {
//          触摸屏
        c.addeventlistener('touchstart', function (event) {
            console.log(1)
            if (event.targettouches.length == 1) {
                event.preventdefault();// 阻止浏览器默认事件,重要
                var touch = event.targettouches[0];
                mousepressed = true;
                draw(touch.pagex - this.offsetleft, touch.pagey - this.offsettop, false);
            }
 
        },false);
 
        c.addeventlistener('touchmove', function (event) {
            console.log(2)
            if (event.targettouches.length == 1) {
                event.preventdefault();// 阻止浏览器默认事件,重要
                var touch = event.targettouches[0];
                if (mousepressed) {
                    draw(touch.pagex - this.offsetleft, touch.pagey - this.offsettop, true);
                }
            }
 
        },false);
 
        c.addeventlistener('touchend', function (event) {
            console.log(3)
            if (event.targettouches.length == 1) {
                event.preventdefault();// 阻止浏览器默认事件,防止手写的时候拖动屏幕,重要
                mousepressed = false;
            }
        },false);
        /*c.addeventlistener('touchcancel', function (event) {
            console.log(4)
            mousepressed = false;
        },false);*/
 
 
 
//         鼠标
        c.onmousedown = function (event) {
            mousepressed = true;
            draw(event.pagex - this.offsetleft, event.pagey - this.offsettop, false);
        };
 
        c.onmousemove = function (event) {
            if (mousepressed) {
                draw(event.pagex - this.offsetleft, event.pagey - this.offsettop, true);
            }
        };
 
        c.onmouseup = function (event) {
            mousepressed = false;
        };
    }
 
    function draw(x, y, isdown) {
        if (isdown) {
            ctx.beginpath();
            ctx.strokestyle = selected2;
            ctx.linewidth = selected1;
            ctx.linejoin = "round";
            ctx.moveto(lastx, lasty);
            ctx.lineto(x, y);
            ctx.closepath();
            ctx.stroke();
        }
        lastx = x; lasty = y;
    }
 
    function cleararea() {
        ctx.settransform(1, 0, 0, 1, 0, 0);
        ctx.clearrect(0, 0, ctx.canvas.width, ctx.canvas.height);
 
        // 清除签名图片
        if(saveimgs.getelementsbytagname('span').length >= 1){
            var clearimg = saveimgs.getelementsbytagname('span')[0];
            saveimgs.removechild(clearimg);
        }
 
    }
</script>
 
</html>

该页面需要引用 jquery-3.3.1.min.js 

前端引用

前端页面除嵌入手写功能页面外,iframe的父窗口需要放置两个元素,一个用于存储手写提交后的base64数据的 asp.net 服务器按钮文本框元素,另一个是用于模拟调用服务器事件的 asp.net 服务器按钮元素。

引用代码如下:

<div  style=" text-align:center">
   <iframe width="520" height="350" id="hw" runat="server" scrolling="no" frameborder="0" src="/cc/module/hw/hw.aspx" ></iframe>
    <asp:textbox id="pbase64" textmode="multiline" style="display:none" runat="server" ></asp:textbox>
    <asp:button id="phw" onclientclick="waittip()" text="后台处理" runat="server" style="display:none" onclick="phw_click" />
</div>

后端处理

手写功能中的提交执行代码将调用如下:

window.parent.document.getelementbyid('pbase64').value = image;
window.parent.document.getelementbyid('phw').click();

其中 pbase64 和 phw 控件为服务器控件,可直接模拟调用 phw 按钮的服务器 click,在这之前其还可以自动处理 onclientclick事件以显示等待界面。请注意 waittip() 执行了一段 javascript 脚本,如下:

function waittip() {
     layer.open({ type: 2, shadeclose: false, content: '正在分析,请稍候...' });
}

这其中引入了 layer 弹出层技术,关于 layer 弹层组件请参照我的文章

这是调用服务器click的事件处理代码,将上传的base64图片转为两种格式的图片文件(png和jpeg)。代码如下:

    protected void phw_click(object sender, eventargs e)
    {
        string mtfilename = "d:\\hw_" + system.guid.newguid().tostring() + ".png";
        string mtfilename2 = "d:\\hw_" + system.guid.newguid().tostring() + ".jpg";
        string dummydata = pbase64.text.trim().replace("data:image/png;base64,", "");
                              
        base64stringtoimage(dummydata, mtfilename);
        if (file.exists(mtfilename)==false)
        {
            base64.imageurl = dummydata;
            layer.open("保存手写图片失败,请重试并提交。" , "'确定'", "error");
            return;
        }
        system.drawing.image img =  system.drawing.image.fromfile(mtfilename);
        using (var b = new system.drawing.bitmap(img.width, img.height))
        {
            b.setresolution(img.horizontalresolution, img.verticalresolution);
 
            using (var g = system.drawing.graphics.fromimage(b))
            {
                g.clear(system.drawing.color.white);
                g.drawimageunscaled(img, 0, 0);
            }
            b.save(mtfilename2, system.drawing.imaging.imageformat.jpeg);
        }
    }

小结

本示例中的前后端代码仅为展示参考,手写功能在支持触屏的设备可以支持手写,也可以用鼠标进行模拟。

服务器调用示例中需要使用 base64stringtoimage(dummydata, mtfilename); 方法由base64数据转化为图片文件,代码如下:

public bool base64stringtoimage(string strbase64, string outputfilename)
{
 
       byte[] arr = convert.frombase64string(strbase64);
       memorystream ms = new memorystream(arr);
       system.drawing.image img = system.drawing.image.fromstream(ms);
       img.save(outputfilename);
       img.dispose();
       if (file.exists(outputfilename))
       {
           return true;
       }
 
       return false;
}

到此这篇关于c#结合javascript实现手写板签名效果的文章就介绍到这了,更多相关c# javascript手写签名内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

  • C# wpf定义ViewModelBase进行简化属性绑定

    C# wpf定义ViewModelBase进行简化属性绑定

    概述绑定机制是wpf的核心,也是界面独立的根本,尤其是使用了mvvm模式,没有业务逻辑的干扰,使得界面得以专注于绚丽效果的实现。在xaml中编写绑定语句后,在业... [阅读全文]
  • C#实现窗体中动态按钮的设计方法

    C#实现窗体中动态按钮的设计方法

    前言在窗体界面中,通常以按钮来代替菜单栏的功能,这种形式虽然给用户一种直观、界面风格各异的感觉,但通常按钮都是以静止的形式显示,当光标移到按钮上时,可以使按钮上... [阅读全文]
  • WPF运行时替换方法实现mvvm自动触发刷新

    WPF运行时替换方法实现mvvm自动触发刷新

    前言我们知道,使用wpf的绑定功能,代码触发界面改变时需要在属性的setter触发propertychanged事件,以达到界面刷新的效果。我们简化了触发流程,... [阅读全文]
  • C#预处理器指令详解与示例

    C#预处理器指令详解与示例

    前言在软件开发中,我们常常需要编写可移植和可配置的代码。c#预处理器指令为我们提供了这样的能力,它允许我们在编译代码之前进行条件编译和文本替换。在本篇文章中,我... [阅读全文]
  • C#实现格式化文本并导入到Excel

    需求在一些导入功能里,甲方经常会给我们一些格式化的文本,类似 csv 那样的纯文本。比如有关质量监督的标准文件(如国家标准、地方标准、企业标准等),还有一此国际标准文件等等。提供给…

    2024年05月26日 编程语言
  • C#实现仿QQ抽屉式窗体的设计方法

    前言qq软件对于绝大多数的人来说再熟悉不过了,它以使用方便、界面美观及功能完善而著称。主要通过使用api函数windowfrompoint和getparent实现仿qq的抽屉式窗体…

    2024年05月26日 编程语言

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com