Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
340 views
in Technique[技术] by (71.8m points)

javascript - 如何将HTML5画布另存为服务器上的图像?(How to save an HTML5 Canvas as an image on a server?)

I'm working on a generative art project where I would like to allow users to save the resulting images from an algorithm.

(我正在从事一个生成艺术项目,我希望允许用户从算法中保存生成的图像。)

The general idea is:

(总体思路是:)

  • Create an image on an HTML5 Canvas using a generative algorithm

    (使用生成算法在HTML5 Canvas上创建图像)

  • When the image is completed, allow users to save the canvas as an image file to the server

    (图像完成后,允许用户将画布作为图像文件保存到服务器)

  • Allow the user to either download the image or add it to a gallery of pieces of produced using the algorithm.

    (允许用户下载图像或将其添加到使用该算法制作的作品库中。)

However, I'm stuck on the second step.

(但是,我坚持第二步。)

After some help from Google, I found this blog post , which seemed to be exactly what I wanted:

(在Google的帮助下,我找到了此博客文章 ,这似乎正是我想要的:)

Which led to the JavaScript code:

(导致了JavaScript代码:)

function saveImage() {
  var canvasData = canvas.toDataURL("image/png");
  var ajax = new XMLHttpRequest();

  ajax.open("POST", "testSave.php", false);
  ajax.onreadystatechange = function() {
    console.log(ajax.responseText);
  }
  ajax.setRequestHeader("Content-Type", "application/upload");
  ajax.send("imgData=" + canvasData);
}

and corresponding PHP (testSave.php):

(和相应的PHP(testSave.php):)

<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) {
  $imageData = $GLOBALS['HTTP_RAW_POST_DATA'];
  $filteredData = substr($imageData, strpos($imageData, ",") + 1);
  $unencodedData = base64_decode($filteredData);
  $fp = fopen('/path/to/file.png', 'wb');

  fwrite($fp, $unencodedData);
  fclose($fp);
}
?>

But this doesn't seem to do anything at all.

(但这似乎根本不起作用。)

More Googling turns up this blog post which is based off of the previous tutorial.

(“更多Google搜索”会根据前一教程改编此博客文章 。)

Not very different, but perhaps worth a try:

(差别不大,但也许值得一试:)

$data = $_POST['imgData'];
$file = "/path/to/file.png";
$uri = substr($data,strpos($data, ",") + 1);

file_put_contents($file, base64_decode($uri));
echo $file;

This one creates a file (yay) but it's corrupted and doesn't seem to contain anything.

(这个创建了一个文件(是),但是它已损坏并且似乎不包含任何内容。)

It also appears to be empty (file size of 0).

(它也似乎是空的(文件大小为0)。)

Is there anything really obvious that I'm doing wrong?

(我做错了什么吗?)

The path where I'm storing my file is writable, so that isn't an issue, but nothing seems to be happening and I'm not really sure how to debug this.

(我存储文件的路径是可写的,所以这不是问题,但是似乎什么也没有发生,而且我不确定如何调试它。)

Edit(编辑)

Following Salvidor Dali's link I changed the AJAX request to be:

(通过Salvidor Dali的链接,我将AJAX请求更改为:)

function saveImage() {
  var canvasData = canvas.toDataURL("image/png");
  var xmlHttpReq = false;

  if (window.XMLHttpRequest) {
    ajax = new XMLHttpRequest();
  }
  else if (window.ActiveXObject) {
    ajax = new ActiveXObject("Microsoft.XMLHTTP");
  }

  ajax.open("POST", "testSave.php", false);
  ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  ajax.onreadystatechange = function() {
    console.log(ajax.responseText);
  }
  ajax.send("imgData=" + canvasData);
}

And now the image file is created and isn't empty!

(现在,图像文件已创建并且不为空!)

It seems as if the content type matters and that changing it to x-www-form-urlencoded allowed the image data to be sent.

(似乎内容类型很重要,将其更改为x-www-form-urlencoded允许发送图像数据。)

The console returns the (rather large) string of base64 code and the datafile is ~140 kB.

(控制台返回(相当大的)base64代码字符串,数据文件约为140 kB。)

However, I still can't open it and it seems to not be formatted as an image.

(但是,我仍然无法打开它,并且它似乎没有被格式化为图像。)

  ask by nathan lachenmyer translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here is an example how to achieve what you need:

(这是一个如何实现您所需的示例:)

1) Draw something (taken from canvas tutorial )

(1) 画点东西 (摘自画布教程 ))

<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
    var canvas = document.getElementById('myCanvas');
    var context = canvas.getContext('2d');

    // begin custom shape
    context.beginPath();
    context.moveTo(170, 80);
    context.bezierCurveTo(130, 100, 130, 150, 230, 150);
    context.bezierCurveTo(250, 180, 320, 180, 340, 150);
    context.bezierCurveTo(420, 150, 420, 120, 390, 100);
    context.bezierCurveTo(430, 40, 370, 30, 340, 50);
    context.bezierCurveTo(320, 5, 250, 20, 250, 50);
    context.bezierCurveTo(200, 5, 150, 20, 170, 80);

    // complete custom shape
    context.closePath();
    context.lineWidth = 5;
    context.fillStyle = '#8ED6FF';
    context.fill();
    context.strokeStyle = 'blue';
    context.stroke();
</script>

2) Convert canvas image to URL format (base64)

(2) 将画布图像转换为URL格式(base64))

var dataURL = canvas.toDataURL();

3) Send it to your server via Ajax

(3) 通过Ajax将其发送到您的服务器)

$.ajax({
  type: "POST",
  url: "script.php",
  data: { 
     imgBase64: dataURL
  }
}).done(function(o) {
  console.log('saved'); 
  // If you want the file to be visible in the browser 
  // - please modify the callback in javascript. All you
  // need is to return the url to the file, you just saved 
  // and than put the image in your browser.
});

3) Save base64 on your server as an image (here is how to do this in PHP , the same ideas is in every language. Server side in PHP can be found here ):

(3) 将base64保存为服务器上的映像 (这是在PHP中执行此操作的方法,每种语言都具有相同的想法。在PHP的服务器端可以在此处找到 ):)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...