我正在从事一个生成艺术项目,我希望允许用户从算法中保存生成的图像。总体思路是:

  • 使用生成算法
  • 在HTML5 Canvas 上创建图像
  • 图像完成后,允许用户将 Canvas 作为图像文件保存到服务器
  • 允许用户下载图像或将其添加到使用该算法制作的作品库中。

  • 但是,我坚持第二步。在Google的帮助下,我找到了这个blog post,它似乎正是我想要的:

    导致了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);
    }
    

    和相应的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);
    }
    ?>
    

    但这似乎什么都没做。

    更多Google搜索会根据先前的教程打开此blog post。差别不大,但也许值得一试:
    $data = $_POST['imgData'];
    $file = "/path/to/file.png";
    $uri = substr($data,strpos($data, ",") + 1);
    
    file_put_contents($file, base64_decode($uri));
    echo $file;
    

    此文件创建了一个文件(是),但该文件已损坏,似乎没有任何内容。它也似乎是空的(文件大小为0)。

    我确实做错了什么吗?我存储文件的路径是可写的,所以这不是问题,但是似乎什么也没有发生,我不确定如何调试它。

    编辑

    按照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);
    }
    

    现在,图像文件已创建,并且不为空!似乎内容类型很重要,将其更改为x-www-form-urlencoded允许发送图像数据。

    控制台返回(相当大的)base64代码字符串,数据文件约为140 kB。但是,我仍然无法打开它,并且它似乎没有被格式化为图像。

    最佳答案

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

  • 绘制一些(取自canvas tutorial)

  • <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>

  • 将 Canvas 图像转换为URL格式(base64)
    var dataURL = canvas.toDataURL();
  • 通过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.
        });

  • 将base64在服务器上另存为镜像(这是how to do this in PHP,每种语言都具有相同的想法。PHP的服务器端可以是found here):
  • 09-30 16:28
    查看更多