15

I want to save multiple canvas into one image using asp.net. I tried with with two canvases, but it is not saving.

Canvas:

    <div style="position:relative; width:456px; padding:0px; margin:0px;">
    <canvas id="boardcanvas" width="456" height="480" style="position: absolute; left: 0;   top: -220px; z-index: 0;"></canvas>
    <canvas id="layer2" width="456" height="480" style="position: absolute;left: 0;   top:-220px; z-index: 1;"></canvas>    
   </div>


 <input type="button" id="btnSave" style="width:150px ; text-align:center;height:30px" name="btnSave" value="Save as Image!" />

Jquery:

<script type="text/javascript">
     // Send the canvas image to the server.
     $(function () {
         $("#btnSave").click(function () {

             can1 = document.getElementById("broadcanvas");
             ctx1 = can1.getContext("2d");
             var coll = document.getElementById("layer2");
             ctx1.drawImage(coll, 0, 0);
             var image = can1.toDataURL("image/png");   

             alert(image);
             image = image.replace('data:image/png;base64,', '');
             $.ajax({
                 type: 'POST',
                 url: 'index.aspx/UploadImage',
                 data: '{ "imageData" : "' + image + '" }',
                 contentType: 'application/json; charset=utf-8',
                 dataType: 'json',
                 success: function (msg) {
                     alert('Image saved successfully !');
                 }
             });
         });
     });
</script>

index.aspx.cs:

using System.IO;
using System.Web.Script.Services;
using System.Web.Services;

[ScriptService]
public partial class index : System.Web.UI.Page
{
    static string path = @"E:\Green\images\\";
    protected void Page_Load(object sender, EventArgs e)
    {


    }
    [WebMethod()]
    public static void UploadImage(string imageData)
    {
       string fileNameWitPath = path + DateTime.Now.ToString().Replace("/", "-").Replace(" ", "- ").Replace(":", "") + ".png";
       using (FileStream fs = new FileStream(fileNameWitPath, FileMode.Create))
        {
           using (BinaryWriter bw = new BinaryWriter(fs))
             {
                byte[] data = Convert.FromBase64String(imageData);
                bw.Write(data);
                bw.Close();
             }
         }
     }
}
Kara
  • 6,115
  • 16
  • 50
  • 57
Anish
  • 768
  • 3
  • 12
  • 34
  • 2
    see if this helps http://stackoverflow.com/questions/3750580/save-many-canvas-element-as-image – ksskr Sep 14 '12 at 08:12
  • @ksskr yes i can get it but I wanted to know how we can integrate those explanation here. I tried their method but it is not showing the output – Anish Sep 14 '12 at 09:04

6 Answers6

2

For the proper working of this code you have to do the below things

  1. Correct the spelling of the canvas id used in the javascript code.
  2. Change the position of the button. Currently button is under the canvas. So can't click on the button.
  3. Create directories Green and Images in E drive. It should be there E:\Green\Images

The working code is.

Javascript

<script type="text/javascript">
        // Send the canvas image to the server.
        $(function () {
            $("#btnSave").click(function () {
                can1 = document.getElementById("boardcanvas");
                ctx1 = can1.getContext("2d");
                var coll = document.getElementById("layer2");
                ctx1.drawImage(coll, 0, 0);
                var image = can1.toDataURL("image/png");

                alert(image);
                image = image.replace('data:image/png;base64,', '');
                $.ajax({
                    type: 'POST',
                    url: 'Default.aspx/UploadImage',
                    data: '{ "imageData" : "' + image + '" }',
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    success: function (msg) {
                        alert('Image saved successfully !');
                    }
                });
            });
        });
    </script>

Html code

<div style="position: relative; width: 456px; padding: 0px; margin: 0px;">
        <canvas id="boardcanvas" width="456" height="480" style="position: absolute; left: 0;
            top: -220px; z-index: 0;">
        </canvas>
        <canvas id="layer2" width="456" height="480" style="position: absolute; left: 0;
            top: -220px; z-index: 1;">
        </canvas>
    </div>
    <input type="button" id="btnSave" style="position: absolute; left: 460px; width: 150px;
        text-align: center; height: 30px; z-index: 2;" name="btnSave" value="Save as Image!" />

Asp.Net side code is OK. Please Try with the above code. Sure it will work (Don't forget to create the directory).

KiranPalode
  • 498
  • 3
  • 8
  • 23
1

Looks like you are converting only one image ("broadcanvas") to a data url. Try this:

var image = ctx1.toDataURL("image/png");

Non-similar variable naming would have helped you spot this quicker.

Owlvark
  • 1,763
  • 17
  • 28
1

The issue here is that you are using the canvas of var coll in drawImage(). You should use its context instead. Here's the fix:

can1 = document.getElementById("broadcanvas");
ctx1 = can1.getContext("2d");
var coll = document.getElementById("layer2");
var ctx2 = coll.getContext("2d");
ctx1.drawImage(ctx2, 0, 0);
var image = can1.toDataURL("image/png");  
anoncoder
  • 68
  • 4
0

Here is a working exemple:

<!DOCTYPE html>
<html>
<body>

<p>Image to use:</p>
<img id="scream" src="http://www.w3schools.com/tags/img_the_scream.jpg" alt="The Scream" width="220" height="277">

<p>Canvas:</p>
<canvas id="myCanvas" width="250" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

<p> Canvas2: </p>
<canvas id="myCanvas2" width="250" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

<script>

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

var img=document.getElementById("scream");
ctx.drawImage(img,30,5);
ctx.drawImage(img,5,30);

var c2=document.getElementById("myCanvas2");

var ctx2=c2.getContext("2d");


ctx2.drawImage(c,0,0)
ctx2.drawImage(img,-10,50);


var image = c2.toDataURL("image/png"); 
console.log(image);

image = image.replace('data:image/png;base64,', '');
console.log(image);

</script>

</body>
</html>

Here is a Fiddle with a working exemple: Fiddle

ElLocoCocoLoco
  • 387
  • 3
  • 11
0

The question might become why you would want to do this type of data munging in the browser when asp.Net and essentially all server side libs can usually take advantage of image processing libraries on the OS, (in linux like GD, GD2, ImageMagick etc).

Is it to avoid having to upload two distinct files to the server? Since with this approach you would only be saving in HTTP transactions, not necessarily in bandwidth.

Just a thought since it doesn't sound like there is anything inherently in the client that is needing to be done here. That may just be because your example is slimmed down.

Nick Sharp
  • 1,881
  • 12
  • 16
0

Here is a trick I do, I have a lot of problems with Making sure all images are loaded and available.

Right after the image is created use the onload event to track if the image is ready for use. I find that using something like the following code does wonders (untested, mainly to be used as a general reference):

//I set to the window event to make sure it stays available. This is handy in many applications that may need to wait.
window.image1 = document.getElementById('img1');
window.image2 = document.getElementById('img2');
window.canv1 = document.getElementById('canv1');
window.canv2 = document.getElementById('canv2');
window.ctx1 = window.canv1.getContext('2d');
window.ctx2 = window.canv2.getContext('2d');
window.imagesLoaded = 0; 

//load the images
window.image1.onload = function(){
  window.imagesLoaded++;
}
window.image2.onload = function(){
  window.imagesLoaded++;
}

//function to handle them all loading
function loaded(){
  if(window.imagesLoaded==2){

    //draw initial images
    ctx1.drawImage(image1,0,0);
    ctx2.drawImage(image2,0,0);

    //at this point you should have 2 canvas's with 2 different images, 
    //now as I understand it you want to save them both to one canvas. 
    //So first grab a new canvas element.
    var newImg1 = window.canv1.toDataURL('image/png');
    var newImg2 = window.canv2.toDataURL('image/png');
    window.canv3 = document.getElementById('canv3');
    window.ctx3 = window.canv3.getContext('2d');

    //this is the tricky part, side by side, 
    //overlapping or top/bottom by manipulating the x,y. 
    //I just make a general example here.
    ctx3.drawImage(newImg1,0,0);
    ctx3.drawImage(newImg2,10,10);

    //finally create the new image as an image, 
    //you can do whatever you need with this
    var newImg3 = window.canv3.toDataURL('image/png');
  }else{
    //set a timeout to retry this function if the images were not ready
    setTimeout(function(){
      loaded();
    },100);
  }
}
loaded();

I may have overused the window object in this example, most likely only will really need it on the "imagesLoaded" variable to make sure I can see its updates, but this way there will be no need to pass parameters to the function as well.

Jordan Ramstad
  • 169
  • 3
  • 8
  • 37