locked
Save img to file from canvas RRS feed

  • Question

  • User1510859543 posted

    I am using canvas and image controls to allow a user to create a signature image and display it and repeat until they are satisfied with their signature.  In the code the save process simply displays the signature in an image control named saveSignature.  I would like to actually save the image control image to a .png file in the remote website folder for that customer (e.g. ~/photos/Jim Smith/). What do I have to do to also save it to a png file on the webserver?  Below is the relevant html and JavaScript.

        <asp:Button ID="BtnShowSignature" runat="server" OnClientClick="return toggleSignature();" Text="1. Enter Signature" ClientIDMode="Static" />
    
        <asp:Panel ID="PanelSignature" runat="server" CssClass="hide" ClientIDMode="Static">
            <div id="canvas">
              <canvas class="" id="newSignature"
                style="; margin: 0; padding: 0; border: 1px solid #c4caac;">
              </canvas>
            </div>
            <script type="text/javascript">
                signatureCapture();
            </script>
            <asp:Button ID="BtnSaveSignature" runat="server" Text="Save signature" OnClientClick="return signatureSave();" />
            <asp:Button ID="BtnClearSignature" runat="server" Text="Clear signature" OnClientClick="return signatureClear();" />
            <br />
            Saved Image
            <br />
            <asp:Image ID="saveSignature" runat="server" ClientIDMode="Static" />
        </asp:Panel>
    
            function signatureSave() {
                var canvas = document.getElementById("newSignature");  // save canvas image as data url (png format by default)
                var dataURL = canvas.toDataURL("image/png");
                document.getElementById("saveSignature").src = dataURL;
                panel = document.getElementById('PanelSignature')
                panel.className = 'hide';
                panel = document.getElementById('PanelDocs')
                panel.className = 'show';
                return false;
            };
    
            function signatureClear() {
                var canvas = document.getElementById("newSignature");
                var context = canvas.getContext("2d");
                context.clearRect(0, 0, canvas.width, canvas.height);
                return false;
            }
            function toggleSignature() {
                panel = document.getElementById('PanelSignature')
                panel.className = 'show';
                var btn = document.getElementById('BtnShowSignature')
                btn.value = 'View Signature';
                return false;
            }
    
    

    Monday, June 15, 2020 3:06 PM

All replies

  • User-719153870 posted

    Hi dlchase,

    You can use JQuery Ajax and Webmethod to achieve your requirement. Please refer to below code:

    aspx:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <script src="Scripts/jquery-3.4.1.min.js"></script>
        <script>
            function signatureSave() {
                var canvas = document.getElementById("newSignature");  
                var dataURL = canvas.toDataURL("image/png");
                document.getElementById("saveSignature").src = dataURL;
                saveImage();
                return false;
            };
    
            function signatureClear() {
                var canvas = document.getElementById("newSignature");
                var context = canvas.getContext("2d");
                context.clearRect(0, 0, canvas.width, canvas.height);
                return false;
            }
            function toggleSignature() {
                panel = document.getElementById('PanelSignature')
                panel.style = "display:block";
                var btn = document.getElementById('BtnShowSignature')
                btn.value = 'View Signature';
                return false;
            }
    
            function saveImage() {
                var image = document.getElementById("saveSignature").src.replace('data:image/png;base64,', '');
                $.ajax({
                    type: "POST",
                    url: "SaveImageDemo.aspx/SaveImage",
                    contentType: "application/json; charset=utf-8",
                    data: '{ "imageData" : "' + image + '" }',
                    dataType: "json",
                    success: function (data) {
                        console.log('success');
                    },
                    error: function (msg) {
                        console.log('fail');
                    }
                });
                return false;
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:Button ID="BtnShowSignature" runat="server"  OnClientClick="return toggleSignature();" Text="1. Enter Signature" ClientIDMode="Static" />
    
                <asp:Panel ID="PanelSignature" runat="server" Style="display:none" ClientIDMode="Static">
                    <div id="canvas">
                        <canvas class="" id="newSignature"
                            style="; margin: 0; padding: 0; border: 1px solid #c4caac;"></canvas>
                    </div>
                    <script type="text/javascript">
                        var context;
                        var drawingSignature = false;
                        var erasingSignature = false;
                        window.onload = function () {
                            var myCanvas = this.document.getElementById("newSignature");
                            this.context = myCanvas.getContext("2d");
                            myCanvas.onmousedown = beginSignature;
                            myCanvas.onmouseup = endSignature;
                            myCanvas.onmouseout = endSignature;
                            myCanvas.onmousemove = doDrawSignature;
    
                            function beginSignature(event) {
                                drawingSignature = true;
                                context.beginPath();
                                context.moveTo(event.pageX - myCanvas.offsetLeft, event.pageY - myCanvas.offsetTop);
                            }
    
                            function endSignature() {
                                drawingSignature = false;
                            }
                            function doDrawSignature(event) {
                                if (drawingSignature) {
                                    context.strokeStyle = "blue";
                                    context.lineTo(event.pageX - myCanvas.offsetLeft, event.pageY - myCanvas.offsetTop);
                                    context.stroke();
                                }
                            }
                        }
                    </script>
                    <asp:Button ID="BtnSaveSignature" runat="server" Text="Save signature" OnClientClick="return signatureSave();" />
                    <asp:Button ID="BtnClearSignature" runat="server" Text="Clear signature" OnClientClick="return signatureClear();" />
                    <br />
                    Saved Image
            <br />
                    <asp:Image ID="saveSignature" runat="server" ClientIDMode="Static" />
                </asp:Panel>
            </div>
        </form>
    </body>
    </html>

    cs:

            [WebMethod]
            public static void SaveImage(string imageData)
            {
                string fileNameWitPath = HostingEnvironment.ApplicationPhysicalPath+"/files/" + DateTime.Now.ToString().Replace("/", "-").Replace(" ", "- ").Replace(":", "") + ".png";
                using (FileStream fs = new FileStream(fileNameWitPath, FileMode.Create))
                {
                    using (BinaryWriter bw = new BinaryWriter(fs))
                    {
                        byte[] data = Convert.FromBase64String(imageData);
                        bw.Write(data);
                        bw.Close();
                    }
                }
            }

    Below is the result of this demo:

    But i don't really think it is a good idea to save the image each time the user "preview" his signature, add another button for "save" might be better.

    Best Regard,

    Yang Shen

    Tuesday, June 16, 2020 3:41 AM
  • User1510859543 posted

    Can you explain the URL in the ajax call? It looks like I need a new page called SaveImageDemo.aspx, is that correct?  Please reply. Thanks.

    Tuesday, June 16, 2020 3:02 PM
  • User-719153870 posted

    Hi dlchase,

    dlchase

    It looks like I need a new page called SaveImageDemo.aspx, is that correct?

    No, no necessary to create a new page.

    dlchase

    Can you explain the URL in the ajax call?

    The url in the ajax call points to the webmethod(SaveImage in this case) in back code of specific page(SaveImageDemo.aspx for example).

    I guess your project is a webform one since you are using asp.net contols, the standard format for url of ajax call in a webform project is url: "{page.aspx}/{webmethod}".

    In my demo, the current page name IS SaveImageDemo(you can find this by the url of browser in my gif) and the webmethod IS SaveImage. So you will need to change the page name and webmethod name to fit your project.

    For more information about how to use JQuery Ajax in a webform project, you can refer to this article.

    In addition, for MVC project, the url format should be url: "{Controller}/{Action}". Please feel free to contact if have any further concern.

    Thanks,

    Yang Shen

    Wednesday, June 17, 2020 1:30 AM
  • User-2054057000 posted

    Can you explain the URL in the ajax call? It looks like I need a new page called SaveImageDemo.aspx, is that correct?  Please reply. Thanks.

    You will need to create web method in your .aspx.cs file in order to perform AJAX call. Refer this article for codes.

    Wednesday, June 17, 2020 3:13 AM
  • User1510859543 posted

    I just discovered that we have to do a full Postback on our page because we need some additional code to handle when saving the image to a file.

    Below is the page markup where the asp.net Image control resides.  I need to save the image that I am loading into the saveSignature Image control.  I have used code to save from an image file but not from a control.  I have the save from a file path code that I have used before shown below the page markup. Thanks.

        <asp:Panel ID="PanelSignature" runat="server" CssClass="hide" ClientIDMode="Static">
            <div id="canvas">
              <canvas class="" id="newSignature"
                style="; margin: 0; padding: 0; border: 1px solid #c4caac;">
              </canvas>
            </div>
            <script type="text/javascript">
                signatureCapture();
            </script>
            <asp:Button ID="BtnSaveSignature" runat="server" Text="Save signature" OnClientClick="return signatureSave();" />
            <asp:Button ID="BtnClearSignature" runat="server" Text="Clear signature" OnClientClick="return signatureClear();" />
            <br />
            Saved Image
            <br />
            <asp:Image ID="saveSignature" runat="server" ClientIDMode="Static" />
        </asp:Panel>
    
    
    Dim bmpImg As Bitmap = Nothing
    Using fileStream As FileStream = File.OpenRead(strFilePath)
        Dim memStream As New MemoryStream()
        memStream.SetLength(fileStream.Length)
        fileStream.Read(memStream.GetBuffer(), 0, CInt(fileStream.Length))
        bmpImg = FilesClass.Resize_Image(fileStream, 2533, 1900)
        bmpImg.Save(filePath, ImageFormat.Jpeg)
        fileStream.Close()
        fileStream.Dispose()
    End Using

    Tuesday, June 23, 2020 5:31 PM