最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - how to save multiple canvas into one image - Stack Overflow

programmeradmin2浏览0评论

I want to save multiple canvas into one image using asp. 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();
             }
         }
     }
}

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();
             }
         }
     }
}
Share Improve this question edited Jan 31, 2014 at 5:20 Kara 6,22616 gold badges53 silver badges58 bronze badges asked Sep 14, 2012 at 6:24 AnishAnish 7684 gold badges12 silver badges34 bronze badges 2
  • 2 see if this helps stackoverflow.com/questions/3750580/… – ksskr Commented Sep 14, 2012 at 8: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 Commented Sep 14, 2012 at 9:04
Add a comment  | 

6 Answers 6

Reset to default 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).

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.

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");  

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

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.

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.

发布评论

评论列表(0)

  1. 暂无评论