OdeToCode IC Logo

Uploading Captured Canvas Images

Monday, January 7, 2013

In "Capturing HTML 5 Video To An Image", Chris asked if we could upload a captured image to the server.

Yes we can!

We will use the same markup from the previous post, but make a simple change to the script. Instead of creating an image on the client, we'll send the image to the server by passing the dataURL generated from the canvas.

(function() {
    "use strict";
    var video, $output;
    var scale = 1;

    var initialize = function() {
        $output = $("#output");
        video = $("#video").get(0);

    var captureImage = function() {
        var canvas = document.createElement("canvas");
        canvas.width = video.videoWidth * scale;
        canvas.height = video.videoHeight * scale;
              .drawImage(video, 0, 0,
                         canvas.width, canvas.height);

        $.post("/image/upload", { dataUrl: canvas.toDataURL() })

    var showImage = function(url) {
        var img = document.createElement("img");
        img.src = url;



On the server we need to parse the incoming data URL. The data URL for an image will contain base 64 encoded bits, like the following:


The ImageDataUrl class will use a regex to pick apart the string and decode the bytes inside.

public class ImageDataUrl
    public ImageDataUrl(string dataUrl)
        var match = _regex.Match(dataUrl);
        MimeType = match.Groups["mimeType"].Value;
        Format = match.Groups["mimeSubType"].Value;
        Bytes = Convert.FromBase64String(match.Groups["data"].Value);

    public byte[] Bytes { get; protected set; }
    public string MimeType { get; set; }
    public string Format { get; protected set; }
    public string SaveTo(string folder)
        var fileName = Guid.NewGuid().ToString() + "." + Format;
        var fullPath = Path.Combine(folder, fileName);

        using(var file = File.OpenWrite(fullPath))
            file.Write(Bytes, 0, Bytes.Length);
        return fileName;

    private static readonly Regex _regex = new Regex(

The ImageDataUrl class can also save the decoded bytes to disk, so all we need to do inside of a controller action is use the class, and return a URL to the newly saved image.

public string Upload(string dataUrl)
    var image = new ImageDataUrl(dataUrl);
    var fileName = image.SaveTo(Server.MapPath("~/uploads"));
    var url = Url.Content("~/uploads/" + fileName);
    return url;

That's one approach to uploading the image.