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
6 Answers
Reset to default 2For the proper working of this code you have to do the below things
- Correct the spelling of the canvas id used in the javascript code.
- Change the position of the button. Currently button is under the canvas. So can't click on the button.
- 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.