As part of a bigger project I am doing right now, I wanted to be able to store data from a HTML Canvas as a byte[]
and save it in Azure blog storage. I thought that this by itself may make an interesting post. I have not posted up any code this time, but all you should need will be available as snippets here.
So the first thing I did was start a new ASP MVC project, which gave me all that I needed to start.
Next, I added a changed Index.Html page to look like the following:
@{
ViewBag.Title = "Home Page";
}
@section Scripts {
<script src="~/Scripts/Index.js"></script>
}
<br/>
<p>This small example saves the canvas to blob storage</p>
<div style="border: 1px solid black; margin: 10px;">
<canvas id="canv" width="600" height="600"></canvas>
</div>
<br/>
<div id="savedImageDiv" style="display:none">
<img id="savedImage" width="100" height="100"/>
</div>
<button type="button" id="saveCanvas" >Save Canvas TO Blob</button>
See how there is a Canvas
element, and an initially hidden Div
, where the Div
contains an image. This Div
will get shown and the image will get filled in with a valid Azure blog storage Url when the Canvas
is saved to blob storage.
So how does this happen. There are not that many moving parts, there are basically the following 4 things needed.
Let's have a look at each of these in turn.
The Web.Config
You will need something like this in your app:
="1.0"="utf-8"
<configuration>
<appSettings>
.....
.....
.....
<add key="azureStorageConnectionString" value="UseDevelopmentStorage=true;" />
</appSettings>
.....
.....
.....
</configuration>
And you would need to install the following Nuget package “WindowsAzure Storage
”.
JavaScript
With the pages HTML in place, we need some JavaScript to post the Canvas
data to the server side controller action. This client side JavaScript is shown below:
$(document).ready(function () {
fillCanvas();
$("#saveCanvas").on("click", function () {
saveCanvas();
});
});
function saveCanvas() {
var canvas = document.getElementById('canv');
var imageData = canvas.toDataURL('image/jpeg', 1);
$.ajax({
type: "POST",
url: "/Home/StoreImage",
dataType: "json",
data: { ImageData: imageData, ImageType: "jpeg" },
success: function (data) {
if (data.StoredOk) {
$('#savedImageDiv').show();
$('#savedImage').attr("src", data.Uri);
alert("success :-)");
} else {
alert("fail :-(");
}
},
error: function () {
alert("fail :-(");
}
});
}
function fillCanvas() {
var canvas = document.getElementById('canv');
var context = canvas.getContext('2d');
context.fillStyle = "rgb(255,255,255)";
context.fillRect(0, 0, 600, 600);
context.fillStyle = "rgb(150,29,28)";
context.fillRect(10, 10, 80, 80);
context.fillStyle = "rgb(100,55,28)";
context.fillRect(200, 200, 20, 80);
}
All that is then left to do is the server side (MVC Controller Action), which is shown below.
Server Side Code
The server side controller action to save the canvas byte[]
into blob storage is shown below. It will also return a JSON object which includes the Blob Uri is stored successfully. Then the JavaScript will examine this JSON response, and decide whether to unhide the Div
containing the image, and set the image Uri to the stored canvas
data. Which is now stored in an Azure blob as an image.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;
using CanvasToBlob.Models;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
namespace CanvasToBlob.Controllers
{
public class HomeController : Controller
{
private readonly string azureStorageConnectionString;
private readonly CloudStorageAccount storageAccount;
public HomeController()
{
azureStorageConnectionString =
ConfigurationManager.AppSettings["azureStorageConnectionString"];
storageAccount =
CloudStorageAccount.Parse(azureStorageConnectionString);
}
public ActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult StoreImage(ImageToStore imageToStore)
{
try
{
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("images");
container.CreateIfNotExists();
container.SetPermissions(
new BlobContainerPermissions
{
PublicAccess = BlobContainerPublicAccessType.Blob
});
CloudBlockBlob blockBlob = container.GetBlockBlobReference(
string.Format("{0}.{1}", Guid.NewGuid().ToString(), imageToStore.ImageType));
string marker = string.Format("data:image/{0};base64,", imageToStore.ImageType);
string dataWithoutJpegMarker = imageToStore.ImageData.Replace(marker, String.Empty);
byte[] filebytes = Convert.FromBase64String(dataWithoutJpegMarker);
blockBlob.UploadFromByteArray(filebytes, 0, filebytes.Length);
JsonImageResult result = new JsonImageResult(true, blockBlob.Uri.ToString());
return this.Json(result);
}
catch (Exception e)
{
JsonImageResult result = new JsonImageResult(false, "");
return this.Json("");
}
}
}
}
Anyway, that is all there is to it. I hope you can use this somehow. Enjoy!