2017年3月29日 星期三

[C#] 電子簽名 + 後台圖檔儲存

這個功能是自己想像的,所以可能有不周全的地方,主要是要寫一個每個禮拜四簽到的電子簽名頁面,每周會用資料夾區分簽名,並且重複簽名會被覆蓋。
感覺還算實用的小功能,可用範圍非常廣泛有關實體簽章類都可通用。

  • 簽名會使用到<canvas></canvas>物件
  • 上傳檔案前會做一個壓縮檔案 toBinary()
  • 存檔是使用HttpPost (C#)



Html:
    
<div>
    <div>
        <canvas height="300" name="SketchPad" style="border: 2px solid gray;" width="900"></canvas>
    </div>
    <input type="button" id="SaveImage" value="簽名" />
</div>


JavaScript:
   
    //取得canvas
    var $canvas = $("[name = 'SketchPad']");
    var ctx = $canvas[0].getContext("2d");
    ctx.lineCap = "round";
    ctx.fillStyle = "white"; //整個canvas塗上白色背景避免PNG的透明底色效果
    ctx.fillRect(0, 0, $canvas.width(), $canvas.height());
    var drawMode = false;
    debugger;
    //canvas點選、移動、放開按鍵事件時進行繪圖動作
    $canvas.mousedown(function (e) {
        ctx.beginPath();
        ctx.strokeStyle = "black";//顏色
        ctx.lineWidth = "4";//粗度
        ctx.moveTo(e.pageX - $canvas.position().left, e.pageY - $canvas.position().top);
        drawMode = true;
    })
    .mousemove(function (e) {
        if (drawMode) {
            ctx.lineTo(e.pageX - $canvas.position().left, e.pageY - $canvas.position().top);
            ctx.stroke();
        }
    })
    .mouseup(function (e) {
        drawMode = false;
    });

    //利用.toDataqURL()將繪圖結果轉成圖檔
    $("#SaveImage").click(function () {
        var buf = toBinary($canvas);
        // Blob
        var blob = new Blob([buf.buffer], {
            type: 'image/png'
        });


        var fd = new FormData();
        fd.append("UploadedImage", blob);//圖檔
        fd.append("fileName", "Test");//檔案名稱,可以透過Url帶入。

        var ajaxRequest = $.ajax({
            type: "POST",
            url: "/api/FileUpload/UploadFile",
            contentType: false,
            processData: false,
            data: fd,
            success: function (msg) {
                debugger;
                alert('簽名 完成!!');
            },
            error: function (xhr, ajaxOptions, thrownError) {
                alert(xhr.status);
                alert(thrownError);
            }
        });

    });

    //壓縮圖檔(Binary)
    function toBinary(canvas) {
        var base64 = canvas[0].toDataURL('image/png'),
            bin = atob(base64.replace(/^.*,/, '')),
            buffer = new Uint8Array(bin.length);
        for (var i = 0; i < bin.length; i++) {
            buffer[i] = bin.charCodeAt(i);
        }
        return buffer;
    }


感覺還是壓縮一下比較好所以還試做了一下。
blob 是壓縮過的檔案大小(11704)
base64 是未壓縮檔案大小(15626)

C#:
上傳檔案並建立當周目錄存放檔案。
建立FileUploadController.cs,這邊主要是走Http因為Call Api比較方便,專案上也比較好用。
    public class FileUploadController : ApiController
    {
        [HttpPost]
        public KeyValuePair UploadFile()
        {
            try
            {
                if (HttpContext.Current.Request.Files.AllKeys.Any())
                {
                    //取得檔案
                    var httpPostedFile = HttpContext.Current.Request.Files["UploadedImage"];
                    //取得檔案名稱
                    var fileName = HttpContext.Current.Request["FileName"];

                    if (httpPostedFile != null)
                    {
                        //取得當周星期四日期
                        DateTime dt = DateTime.Now;
                        string tmp = dt.DayOfWeek.ToString();//tmp = Thursday
                        string tmp2 = dt.DayOfWeek.ToString("d");//tmp2 = 4 
                        int d = 4 - Convert.ToInt32(tmp2);
                        DateTime dt4 = dt.AddDays(d);

                        string path = HttpContext.Current.Server.MapPath("~/UploadedFiles/" + dt4.ToString("yyyy-MM-dd"));
                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }

                        //取得存檔目錄
                        var fileSavePath = Path.Combine(path, fileName + ".png");

                        //存檔
                        httpPostedFile.SaveAs(fileSavePath);

                        return new KeyValuePair(true, "上傳檔案成功");
                    }

                    return new KeyValuePair(true, "無法取得檔案");
                }

                return new KeyValuePair(true, "沒有檔案");
            }
            catch (Exception ex)
            {
                return new KeyValuePair(false, ex.Message);
            }
        }
    }






參考
w3school 範例教學
用100行實現HTML5可存檔塗鴉版

沒有留言:

張貼留言