Srikanth Technologies

How to use Webcam to snap photo and store in Database

In this blog, we will see the following :

This blog uses the following products and technologies.

How to enable Webcam and stream it to Video control

In order to use Webcam of our system, we need to seek permission of the user to use it. Method navigator.getuserMedia() is used to take permission from user and stream Webcam input to Video control when user grants permission. The following is the syntax of getUserMedia().

    navigator.getUserMedia(constraints, successCallback, errorCallback);

Read more about getUserMedia() here.

When this page is run, user is prompted to accept or deny the permission with a prompt like shown below.

Prompting user for permission

Once user clicks on Accept button, we start streaming Webcam input to Video control by setting src property of Video control to stream. It is also requied to play() video so that whatever is captured by Webcam is continously displayed in Video control.

The following is part of the page that does what we have seen so far.

        var canvas, context, video;

        // jQuery document ready event
        $(function () {
            canvas = document.getElementById("canvas");
            context = canvas.getContext("2d");
            video = document.getElementById("video");

            // different browsers provide getUserMedia() in differnt ways, so we need to consolidate 
            navigator.getUserMedia = navigator.getUserMedia ||  navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
            
            if (navigator.getUserMedia) {
                navigator.getUserMedia(
                   { video : true }, // which media
                   function (stream) {   // success function
                       video.src = window.URL.createObjectURL(stream);
                       video.onloadedmetadata = function (e) {
                           video.play();
                       };
                   },
                   function (err) {  // error function 
                       console.log("The following error occured: " + err.name);
                   }
              );
            } 
            else {
                console.log("getUserMedia not supported");
            }
        });

How to snap photo with Webcam and display it using Canvas

The following code shows how to snap a photo with Webcam (as its input is streamed to Video control) and display photo in Canvas.

    function takePhoto() {
          context.drawImage(video, 0, 0, 640, 480);  // takes content from video control at this point and draws on Canvas
    }

After photo is snapped

How to send contents of a Canvas to an ASP.NET page using Ajax Post request

The next task is to send Canvas contents to server-side code (ASP.NET Page here, however you can use any other server-side code for this purpose) using AJAX Post request with jQuery's ajax() method.

We use toDataURL() method of Canvas object to convert image displayed in canvas to base64 format. The return value of this function is a string and sent to server as part of Post request.

Read more about toDataURL() method here.

    function savePhoto() {
            var data  = canvas.toDataURL();  // convert canvas contents to base64 format using png format
            var title = $("#title").val();
        
            $.ajax({
                type: "POST",
                url: "savephoto.aspx",
                data: {
                    photo: data,     // image
                    title : title    // title 
                }
            }).done(function (o) {  // success function 
                alert("Photo Saved Successfully!");
            });
    }

Here is the complete code along with HTML markup for Video and Canvas.

webcam.html

<!DOCTYPE html>
<html>
<head>
    <script src="jquery.js"></script>
    <title>Sanp Photo</title>
    <script>
        var canvas, context, video, videoObj;

        $(function () {
            canvas = document.getElementById("canvas");
            context = canvas.getContext("2d");
            video = document.getElementById("video");

            // different browsers provide getUserMedia() in differnt ways, so we need to consolidate 
            navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||  navigator.mozGetUserMedia;

            if (navigator.getUserMedia) {
                navigator.getUserMedia(
                   { video : true }, // which media
                   function (stream) {   // success function
                       video.src = window.URL.createObjectURL(stream);
                       video.onloadedmetadata = function (e) {
                           video.play();
                       };
                   },
                   function (err) {  // error function 
                       console.log("The following error occured: " + err.name);
                   }
              );
            } 
            else {
                console.log("getUserMedia not supported");
            }
        });

        function takePhoto() {
            context.drawImage(video, 0, 0, 640, 480);
        }

        function savePhoto() {
            var data = canvas.toDataURL();
            var title = $("#title").val();

            $.ajax({
                type: "POST",
                url: "savephoto.aspx",
                data: {
                    photo: data,
                    title: title
                }
            }).done(function (o) {
                alert("Photo Saved Successfully!");
            });
        }
    </script>
</head>
<body>
    Enter Title : <input type="text" name="title" id="title" />
    <button id="btnSnap" onclick="takePhoto()">Snap Photo</button>
    <button id="btnSave" onclick="savePhoto()">Save Photo</button>
    <a href="ListPhotos.aspx">ListPhotos.aspx</a>
    <p />
    <video id="video" width="640" height="480" autoplay></video>
    <canvas style="float:right" id="canvas" width="640" height="480"></canvas>
</body>
</html>

How to store contents of Canvas in SQL Server database as Image column

The following code in ASP.NET page is used to stored image in SQL Server database. We open connection to LocalDb and insert a row into PHOTOS table.

We need to strip off the extra information that is at the beginning of the string (shown below). Convert base64 string to an array of bytes using Convert.FromBase64String() method.

    data:image/png;base64,contents 
Use parameter of type Image with SqlCommand object to set array of bytes to Image column as shown in the code below.

savephoto.aspx

<%@ Page Language="C#" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<!DOCTYPE html>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            SqlConnection con = new SqlConnection
                          (@"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True");
            string qry = "insert into Photos (title,photo) values(@title, @photo)";
            SqlCommand cmd = new SqlCommand(qry, constr);
            // create Parameters
            cmd.Parameters.AddWithValue("@title", Request.Form["title"]);
            SqlParameter photoParam = new SqlParameter("@photo", SqlDbType.Image);
            String source = Request.Form["photo"];
            // remove extra chars at the beginning
            source = source.Substring(source.IndexOf(",") + 1);
            byte[] data = Convert.FromBase64String(source);
            photoParam.Value = data;
            cmd.Parameters.Add(photoParam);

            //Open connection and execute insert query.
            con.Open();
            cmd.ExecuteNonQuery();
            con.Close();
        }
        catch (Exception ex)
        {
            Trace.Write(ex.Message);
        }
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
</body>
</html>

How to display list of images in PHOTO table using DataList

We use DataList control to display title and photo taken from PHOTOS table. As rows are bound to DataList control, we use ItemDataBound event to copy image to Image control in ItemTemplate.

Image in PHOTO column of the table is in the form of an array of bytes. We need to convert that base64 format and set it to ImageUrl property of Image control. We also need to prepend "data:image/png;base64," in order to treat the string as an image.

List of Photos from Database

Here is the complete code for ListPhotos.aspx.

ListPhotos.aspx

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<!DOCTYPE html>
<script runat="server">

    DataSet ds; 
    
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            SqlConnection con = new SqlConnection
                           (@"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True");
            SqlDataAdapter da = new SqlDataAdapter("select * from photos",con);
            ds = new DataSet();
            da.Fill(ds,"photos");
            DataList1.DataSource = ds.Tables[0];
            DataList1.DataBind();
        }
        catch (Exception ex)
        {
            Trace.Write(ex.Message);
        }
    }

    protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
    {
       Image img =  e.Item.FindControl("photo") as Image;
       DataRow row = ds.Tables[0].Rows[e.Item.ItemIndex];
       byte [] bytes  = (byte []) row["photo"];
        
       string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
       img.ImageUrl = "data:image/png;base64," + base64String;
    }
    
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>List Of Photos</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:DataList ID="DataList1" runat="server"  OnItemDataBound="DataList1_ItemDataBound">
            <ItemTemplate>
                <h2> <%# Eval("title") %></h2>
                <asp:Image ID="photo" runat="server" />
              
            </ItemTemplate>
        </asp:DataList>
    </div>
    </form>
</body>
</html>