Saving HTML 5 canvas as Image in ASP.NET MVC

Sheonarayan
Posted by in ASP.NET MVC category on for Intermediate level | Points: 250 | Views : 87031 red flag
Rating: 5 out of 5  
 2 vote(s)

In this article, we will learn how to save HTML 5 canvas as image on the server in ASP.NET MVC.

Introduction


In HTML 5, creating a graphics has become easier in the browser using Canvas element and JavaScript. There are few articles on DotNetFunda.com already that demonstrate the power of Canvas, one more article on this topic is introducing Canvas in HTML 5.

One of my previous article explained how to save Canvas as image in ASP.NET web form , this article explains how to save Canvas as image in ASP.NET MVC as saving canvas as image in ASP.NET MVC is not similar to saving Canvas as image in ASP.NET Web form.

Objective

The objective of this article is to explain the steps of saving HTML 5 canvas as Image on the server using ASP.NET MVC.

Code explanation to save canvas as Image in ASP.NET MVC


Let's start by creating a Canvas element on the View page. In this article, an example of Drawing section of KidsFunda.com is taken.



View Code


In this case, canvas element code looks like below (entire code of the view page is not shown here as that would make us difficult to understand this topic easily.)

Code to create Drawing area using Canvas
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "drawingForm" }))
    {

           <input type="hidden" name="imageData" id="imageData" />
           <input type="button" id="btnSave" value="Save Drawing" />

           <canvas id="kfCanvas" width="800px" height="500px;" style="border: 3px dotted #000;
             cursor:crosshair;">Sorry, your browser doesn't support canvas technology.
           </canvas>

    }
There are few things to notice in the above code snippet
  1. The parameter of the @Html.BeginForm, the purpose of keeping those parameters were to specify an id attribute of the Form element on the view page so that we can refer this form easily in Javascript.
  2. A hidden field named "imageData" that would be used to send the canvas data to the server.
Code to post the Canvas data to the server
$("#btnSave").click(function () {
    var form = $("#drawingForm");
    var image = document.getElementById("kfCanvas").toDataURL("image/png");
    image = image.replace('data:image/png;base64,', '');
    $("#imageData").val(image);
    form.submit();
});
In the above code snippet, 
  1. On click of the button, we are getting the Form element of the page where our Canvas and hidden elements are there.
  2. we are getting the canvas element and calling .toDataURL function by passing the type of image we want to save as.
  3. we are replacing the token that is attached by calling the toDataURL with empty as we do not need it.
  4. we are setting the image (canvas element data) to the hidden element 
  5. then submitting the form.

Controller Code


The controller code that is responsible to render the view page and to save the canvas as Image looks like below. Apart from other standard namespaces, we need to add System.IO namespace in the controller.

        public ActionResult Create()
        {
            return View(new DrawingModel());
        }

        [HttpPost]
        [Authorize]
        [ValidateAntiForgeryToken]
        public ActionResult Create(DrawingModel model, string imageData)
        {
            string fileName = "MyUniqueImageFileName.png";
            string fileNameWitPath = Path.Combine(Server.MapPath("~/FolderToSave"), fileName);

            using (FileStream fs = new FileStream(fileNameWitPath, FileMode.Create))
            {
                using (BinaryWriter bw = new BinaryWriter(fs))
                {
                    byte[] data = Convert.FromBase64String(imageData);
                    bw.Write(data);
                    bw.Close();
                }
                fs.Close();
            }

            model.FileName = fileName;
            model.IsPublished = true;
            model.UserName = User.Identity.Name;
            model.ViewCount = 0;
            model.CreatedDateTime = DateTime.Now;

            if (ModelState.IsValid)
            {
                db.DrawingModels.Add(model);
                db.SaveChanges();

                return RedirectToAction("Index");
            }
            return View(model);
        }
In the above code snippet, the first Create method simply returns the View by passing the Model.

The second Create method actually does all the work that we wanted to do. In the second create method we are doing following things
  1. we are getting the physical path and the file name (.png file name) to save our canvas as image
  2. passing necessary parameter to the FileStream object to save the image to 
  3. using BinaryWriter to write the data to the file
  4. before we write the data, we are converting the canvas data coming as string to this method as an array of bytes using Convert.FromBase64String method.
  5. Remaining code is simply binding the necessary data to the Model object to save a record against this image into the database. You can ignore this part if you just want to save the canvas as image on the server and do not want to any database activity.
Below is the image saved from canvas.



We can even save the image as .jpg however that doesn't maintain necessary background of the image (at least in my case). Just replace .png to .jpg from the above code snippet.


Conclusion


Searching for the solution of saving canvas as Image in ASP.NET MVC was not easy as I spend more than enough time doing it but couldn't get it. Hope this article would help people looking for that solution.

Thanks for reading and do let me know your feedback by responding to this article. 
Page copy protected against web site content infringement by Copyscape

About the Author

Sheonarayan
Full Name: Sheo Narayan
Member Level: HonoraryPlatinum
Member Status: Administrator
Member Since: 7/8/2008 6:32:14 PM
Country: India
Regards, Sheo Narayan http://www.dotnetfunda.com

Ex-Microsoft MVP, Author, Writer, Mentor & architecting applications since year 2001. Connect me on http://www.facebook.com/sheo.narayan | https://twitter.com/sheonarayan | http://www.linkedin.com/in/sheonarayan

Login to vote for this post.

Comments or Responses

Posted by: Bangkalog on: 7/22/2014 | Points: 25
It's not working on my project i need help.

VIEW
@using (Html.BeginForm("SampleCaptureImage", "Warehouse", FormMethod.Post))

{
<div style="padding: 20px;" align="center">
<h3>Camera</h3>
<video id="video" style="max-width: 100%; height: auto; width: auto\9; display: block; margin-left: auto; margin-right: auto;" width="640" height="480" autoplay></video>
<h3>Photo</h3>
<canvas id="canvas" name="canvas" style="max-width: 100%; height: auto; width: auto\9; display: block; margin-left: auto; margin-right: auto;" width="640" height="640"></canvas>
<br />
//this is to snap the camera video and save the image t o c anv as.
<button type="button" id="snap">Snap Photo</button>

<input type="hidden" name="imageData" id="imageData" />
<input type="submit" id="btnSave" value="Save Drawing" />

</div>
}
<script>
$("#btnSave").click(function () {
var form = $("#drawingForm");
var image = document.getElementById("kfCanvas").toDataURL("image/png");
image = image.replace('data:image/png;base64,', '');
$("#imageData").val(image);
form.submit();
});
</script>


CONTROLLER
public ActionResult SampleCaptureImage(string imageData) //no data receive when button save

{
return View();
}

Login to post response

Comment using Facebook(Author doesn't get notification)