Как сохранить несколько холстов в одно изображение
Я хочу сохранить несколько холстов в одно изображение с помощью asp.net. Я пробовал с двумя полотнами, но это не спасает.
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();
}
}
}
}
Ответы
Ответ 1
Для правильной работы этого кода вам нужно сделать следующее:
- Исправьте написание идентификатора canvas, используемого в javascript-коде.
- Измените положение кнопки. В настоящее время кнопка находится под холстом. Поэтому не могу нажать кнопку.
- Создание каталогов Green и изображений в E-диске. Он должен быть там E:\Green\Images
Рабочий код.
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
<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 в порядке.
Пожалуйста, используйте вышеуказанный код. Конечно, это сработает (не забудьте создать каталог).
Ответ 2
Похоже, вы конвертируете только одно изображение ( "widecanvas" ) в URL-адрес данных. Попробуйте следующее:
var image = ctx1.toDataURL("image/png");
Неподобное имя переменной помогло бы вам быстрее определить это.
Ответ 3
Вот пример:
<!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>
Вот сценарий с рабочим примером: Fiddle
Ответ 4
Проблема в том, что вы используете холст var coll
в drawImage()
. Вместо этого вы должны использовать его контекст. Здесь исправление:
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");
Ответ 5
Может возникнуть вопрос, почему вы захотите сделать этот тип обработки данных в браузере, когда asp.Net и, по сути, все серверные библиотеки могут использовать библиотеки обработки изображений в ОС (в Linux, например GD, GD2, ImageMagick и т.д.).
Не нужно ли загружать на сервер два разных файла? Поскольку при таком подходе вы сохраняете только транзакции HTTP, не обязательно в полосе пропускания.
Просто мысль, так как это не похоже на то, что в клиенте есть что-то неотложное, что нужно делать здесь. Это может быть просто потому, что ваш пример уменьшен.
Ответ 6
Вот трюк, который у меня есть, у меня много проблем с обеспечением того, чтобы все изображения были загружены и доступны.
Сразу после создания изображения используйте событие onload
для отслеживания готовности изображения к использованию. Я считаю, что использование чего-то вроде следующего кода делает чудеса (непроверенные, в основном для использования в качестве общей ссылки):
//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 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();
Возможно, я использовал в этом примере объект окна, скорее всего, он действительно понадобится в переменной "imagesLoaded", чтобы убедиться, что я могу видеть его обновления, но таким образом не будет необходимости передавать параметры функции также.