亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#結合JavaScript實現手寫板簽名效果

 更新時間:2024年04月28日 09:17:33   作者:初九之潛龍勿用  
這篇文章主要為大家詳細介紹了C#如何結合JavaScript實現手寫板寫字并上傳到服務器進行處理,感興趣的小伙伴可以跟隨小編一起學習一下

應用場景

我們最近開發(fā)了一款筆跡測試功能的程序(測試版),用戶在手寫板上手寫簽名,提交后即可測試出被測試者的心理素質評價分析。類似功能的場景還比如,在銀行柜臺 辦理業(yè)務,期間可能需要您使用手寫設備進行簽名并確認;保險續(xù)期小程序,到期后需要你在確認續(xù)期條款后,在手機上提供的簽名區(qū)域進行簽名并提交確認。

實現效果

筆跡測試顯示界面如下:

可選擇畫筆顏色(默認為黑色筆) ,在虛線框內可隨便寫一段文字,點擊提交即可。當然程序還提供拍照上傳功能,這里不再詳述。下面我們開始介紹,C#如何結合JavaScript實現手寫板寫字并上傳到服務器進行處理。

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

操作系統: Windows Server 2019 DataCenter

手寫觸屏設備:Microsoft Surface Pro 9

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

開發(fā)工具: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>

后端處理

手寫功能中的提交執(zhí)行代碼將調用如下:

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

其中 pbase64 和 phw 控件為服務器控件,可直接模擬調用 phw 按鈕的服務器 click,在這之前其還可以自動處理 OnClientClick事件以顯示等待界面。請注意 waittip() 執(zhí)行了一段 javascript 腳本,如下:

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

這其中引入了 Layer 彈出層技術,關于 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手寫簽名內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 在WCF數據訪問中使用緩存提高Winform字段中文顯示速度的方法

    在WCF數據訪問中使用緩存提高Winform字段中文顯示速度的方法

    這篇文章主要介紹了在WCF數據訪問中使用緩存提高Winform字段中文顯示速度的方法,是非常實用的功能,需要的朋友可以參考下
    2014-09-09
  • C#實現撲克游戲(21點)的示例代碼

    C#實現撲克游戲(21點)的示例代碼

    21點又名黑杰克,該游戲由2到6個人玩,使用除大小王之外的52張牌,游戲者的目標是使手中的牌的點數之和不超過21點且盡量大。本文將用C#實現這一經典游戲,需要的可以參考一下
    2022-08-08
  • 完美解決c# distinct不好用的問題

    完美解決c# distinct不好用的問題

    這篇文章主要介紹了完美解決c# distinct不好用的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • c# dynamic的好處

    c# dynamic的好處

    這篇文章主要介紹了c# dynamic的好處,以示例代碼幫助大家更好的了解和學習,感興趣的朋友可以了解下
    2020-12-12
  • c#讀取圖像保存到數據庫中(數據庫保存圖片)

    c#讀取圖像保存到數據庫中(數據庫保存圖片)

    這篇文章主要介紹了使用c#讀取圖像保存到數據庫中的方法,大家參考使用吧
    2014-01-01
  • C#從控制臺讀取字符串的方法

    C#從控制臺讀取字符串的方法

    這篇文章主要介紹了C#從控制臺讀取字符串的方法,實例分析了ReadLine方法的基本使用技巧,需要的朋友可以參考下
    2015-06-06
  • C#實現用于生成條形碼的類

    C#實現用于生成條形碼的類

    這篇文章主要介紹了C#實現用于生成條形碼的類,涉及C#生成條形碼的原理與實現技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • c# richtextbox更新大量數據不卡死的實現方式

    c# richtextbox更新大量數據不卡死的實現方式

    這篇文章主要介紹了c# richtextbox更新大量數據不卡死的實現方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • C#串口通信總是丟數據的原因及解決方案

    C#串口通信總是丟數據的原因及解決方案

    在上位機開發(fā)中,串口通信是一個非常常見的通信方式,尤其是在與嵌入式設備、PLC、傳感器等硬件設備進行交互時,串口通信簡單、直接且廣泛應用,但它也有自己的局限性,那么,為什么你的C#串口通信總是丟數據?本文將深度分析串口通信丟數據的原因,并提供一些有效的解決方案
    2025-02-02
  • C#線程處理系列之線程池中的I/O線程

    C#線程處理系列之線程池中的I/O線程

    這篇文章主要介紹了C#線程處理系列之線程池中的I/O線程,在這篇文章中將介紹如何用線程池中的I/O線程來執(zhí)行I/O操作,感興趣的小伙伴們可以參考一下
    2016-04-04

最新評論