Over the past week I have been working on the problem of identifying if an HTML5 canvas is empty or not. That is to determine if something is written or not on the canvas.
To begin with, I searched if there are any existing solutions and found one which suggests to check every pixel with in the canvas area. Of course this could be a solution, but I was looking for some thing that suits my case better. I am working on a web application having several forms where canvas is used to take signatures either using a stylus/ mouse (as in touch screen laptops) or with finger touch (Iphone/ IPad) events. Also each web page may have up to four canvas boxes. So the method of checking each pixel could increase the processing time for each web page.
Also i was more inclined towards a solution using the properties of canvas or the programming language (in this case ASP .Net) and with less inclination towards the old school method of checking each pixel. One such property is the 'toDataURL', which retrieves the canvas data in string format. This string data can be converted as a byte array and there by we can get the size of the image. But the size of the byte array is not zero, even when the canvas is empty. When the canvas is empty, the default header information adds up to some size. Adding to this problem is the size of this default header is different in different browsers like safari, chrome, opera and firefox.
Initially i thought of checking the default size for each browser and use it to determine if the canvas is empty, but later found that this header size changes for different sizes of canvas and it may change in the later versions of the browsers. Still as of today, all the browsers are yet to comply to all the set standards of HTML5.
Finally, i came up with a solution where the emptiness of the canvas is determined dynamically, by comparing the size of the canvas before writing (during the page-load event) and after writing (when form 'submit' button is pressed). The data-URL of the canvas is retrieved and stored when the canvas is empty (during the page load event) and the data-URL of the canvas is retrieved again when the page is submitted. By checking the difference between the two data-URLs we can determine the status of the canvas.
The sample code below, explains the implementation.
Thus by using the canvas 'toDataURL' property and the page_load events, we could determine if the canvas is empty.
To begin with, I searched if there are any existing solutions and found one which suggests to check every pixel with in the canvas area. Of course this could be a solution, but I was looking for some thing that suits my case better. I am working on a web application having several forms where canvas is used to take signatures either using a stylus/ mouse (as in touch screen laptops) or with finger touch (Iphone/ IPad) events. Also each web page may have up to four canvas boxes. So the method of checking each pixel could increase the processing time for each web page.
Also i was more inclined towards a solution using the properties of canvas or the programming language (in this case ASP .Net) and with less inclination towards the old school method of checking each pixel. One such property is the 'toDataURL', which retrieves the canvas data in string format. This string data can be converted as a byte array and there by we can get the size of the image. But the size of the byte array is not zero, even when the canvas is empty. When the canvas is empty, the default header information adds up to some size. Adding to this problem is the size of this default header is different in different browsers like safari, chrome, opera and firefox.
Initially i thought of checking the default size for each browser and use it to determine if the canvas is empty, but later found that this header size changes for different sizes of canvas and it may change in the later versions of the browsers. Still as of today, all the browsers are yet to comply to all the set standards of HTML5.
Finally, i came up with a solution where the emptiness of the canvas is determined dynamically, by comparing the size of the canvas before writing (during the page-load event) and after writing (when form 'submit' button is pressed). The data-URL of the canvas is retrieved and stored when the canvas is empty (during the page load event) and the data-URL of the canvas is retrieved again when the page is submitted. By checking the difference between the two data-URLs we can determine the status of the canvas.
The sample code below, explains the implementation.
HTML Part:
<canvas id=”canvasLayout” width=”400” height=”200” />
<asp:HiddenField ID=”emptyCanvas” runat=”server” /> // to store the value of the empty canvas
<asp:HiddenField ID=”dataCanvas” runat=”server” /> // to store the value of canvas at page submit along with any data.
JavaScript Part:
During the page-load event the java-script’s ‘window.onload’ is executed by default. In the 'onload' event the size of the empty canvas data is captured. The function 'SaveImage' is triggered when the form/page is submitted.
<script type="text/javascript">
function getImageURL(element) {
var canvasElement = document.getElementById(element);
var imageDataUrl = canvasElement.toDataURL("image/png");
return imageDataUrl;
}
window.onload = function(){
var tempEmptyCanvas = document.getElementById(‘’);
tempEmptyCanvas.value = getImageURL(“canvasLayout”);
}
function SaveImage(){
var tempDataCanvas = document.getElementById(‘’);
tempDataCanvas.value = getImageURL(“canvasLayout”);
}
script>
Server Side:
On the server side, the values in the two hidden fields are retrieved and their sizes are computed. If the difference between their sizes is 0, then the canvas is empty, else there is some data on canvas.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
String emptyCanvasValue = emptyCanvas.Value;
String dataCanvasValue = dataCanvas.Value;
byte[] whenEmpty = Convert.FromBase64String(emptyCanvasValue);
byte[] whenNotEmpty = Convert.FromBase64String(dataCanvasValue);
int checkCanvasDataSize = whenNotEmpty.Length – whenEmpty.Length;
if(checkCanvasDataSize == 0)
{
//Canvas empty
}
else
{
//Canvas Not empty
}
}
Thus by using the canvas 'toDataURL' property and the page_load events, we could determine if the canvas is empty.
2 comments:
Can you post the code?, i'm missing something in the example, how do you fill the hieden fieles.
Thank you,
Ok, I have missed out a couple of things here.
In ‘window.onload’ function and in ‘SaveImage()’ function, have to include the hidden field.
window.onload = function(){
var tempEmptyCanvas = document.getElementById(‘<%=emptyCanvas.ClientID%>’);
tempEmptyCanvas.value = getImageURL(“canvasLayout”);
}
Here ‘emptyCanvas’ is the hidden field that stores the canvas content (default header data) during page load.
function SaveImage(){
var tempDataCanvas = document.getElementById(‘<%=dataCanvas.ClientID%>’);
tempDataCanvas.value = getImageURL(“canvasLayout”);
}
Here ‘dataCanvas’ is the hidden filed that retrieves the data from canvas when page is ‘submit’ted.
Also on the page_load() method, bind the SaveImage() function to the submit button.
btnSubmit.Attributes.Add("onclick", "JavaScript: SaveImageAs();");
On the server side, the hidden field values are accessed as emptyCanvas.Value and dataCanvas.Value.
Also, I’ll update the blog with these corrections.
Post a Comment