HTML5画布的toDataURL方法返回空白图片

4

从一块空白的画布开始:

<canvas id='myCanvas' width='800' height='600'></canvas>

接下来要初始化画布:

  function init_canvas(){
    var canvas = document.getElementById('myCanvas');
    context = canvas.getContext('2d');
    context.lineCap = 'round';
    // fill it with white background
    context.save();
    context.fillStyle = '#fff';
    context.fillRect(0, 0, context.canvas.width, context.canvas.height);
    context.restore();
    return;
  }

接下来在画布上进行一系列的绘制。

然后尝试使用后端的ajax和PHP将其保存到服务器上。

在客户端:

var img = canvas.toDataURL('image/png');
// strip the leading garbage.
img.substr(img.indexOf(',')+1).toString();

将生成的字符串直接带入PHP并使用base64_decode()解密该字符串即可... 图像总是正确的大小,但它没有任何绘图 - 只有一个透明的图像。这似乎不是PHP中base64_decode()的问题,它似乎是安全问题或其他什么原因导致的。这在Firefox 4和最新的Chrome浏览器都会失败。
使用"image/png"头将结果png图像转储到Firefox时,在错误控制台中显示如下内容:
Error: Image corrupt or truncated: http://somewhere.com/showimage.php
Source file: http://somewhere.com/showimage.php

但是...就我所知,该图像并未损坏或截断,除非toDataURL()在所有地方都无法正常工作,因为php部分只是对toDataURL()的结果进行base64_decode()。

有什么想法吗?

谢谢!


你可能需要查看此示例的源代码。http://motyarblog.000space.com/imagetouri.php使用了jQuery。你的问题可能在于`canvas.toDataURL`是图像的base64字符串,如果超过255个字符,则无法作为$_GET传递。 - Lawrence Cherone
已经考虑过这一点并确认我正在进行XHR的POST操作。在后端,我将base64编码的图像转储到文本文件中,长度正常,是一个真正的b64字符串,可以正常解码,只是一个空白图像。 - Erick
2
你在 PHP 文档中看到了“base64_decode”函数的这个注释吗? - robertc
robertc... 哇,真是个笑话。整个将空格替换为加号的事情就是这样。把那条评论作为回复,我会将其标记为解决方案。谢谢大家。 - Erick
4个回答

7

您是否看到了PHP文档中base64_decode函数的这条评论

If you want to save data that is derived from a Javascript canvas.toDataURL() function, you have to convert blanks into plusses. If you do not do that, the decoded data is corrupted:

<?php
  $encodedData = str_replace(' ','+',$encodedData);
  $decocedData = base64_decode($encodedData);
?>

0

不是的。robertc实际上已经给出了答案,但只是在评论中,而不是在回答中。谢谢你的关注。 - Erick
1
@Erick 我会将其添加为答案 ;) - robertc

0

这个可以正常工作,不会返回空白图像。

saveImage.php

 <?php 
        $result = array();  
        $encodedData = explode("," , $_POST['imgData'])[1];
        $encodedData = str_replace(' ','+',$encodedData);
        $decocedData = base64_decode($encodedData); 
        //Location to where you want to save image
        $NewFileName = './photos/'.$_POST['imgName'].'.jpg';
        file_put_contents($NewFileName,$decocedData);
        $result['status'] = 1;
        $result['saveImage'] = $NewFileName;
        echo json_encode($result);
    ?>

script.js

<script>
//This post the data to server on fly

function saveImage(canvasData,FileName) {
  var xmlHttpReq = false;

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

  ajax.open("POST", "saveImage.php", false);
  ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  ajax.onreadystatechange = function() {

    if (this.readyState == 4 && this.status == 200) {
        var rawArr = JSON.parse(this.responseText);
        var ImagePreviewer= document.getElementById("ImagePreviewer");
    ImagePreviewer.src=rawArr.saveImage;
    //console.log(rawArr.saveImage);
    }

  }
  ajax.send("imgData=" + canvasData+"&imgName=" + FileName);
}
// Call this with button click or whatever you want 
function saveJPG(filename) {
//do other logic here
var dataURL = TheCanvas.toDataURL("image/jpg");
    saveImage(dataURL,filename);
}
<script>

-1
在JavaScript中,对于那些支持该方法的浏览器,使用默认类型"image/png"发送canvas.toDataURL()的结果。
var imageInfo = canvas.toDataURL();

创建 PNG 文件的直接方法:

<?php
$imageInfo = imageInfoFromBrowser(); // Your method to get the data
$image = fopen($imageInfo, 'r');
file_put_contents("fileName.png", $image);
fclose($image);
?>

我已经在PHP 5.3中使这个工作正常,对于其他版本,请检查。

用于在PHP上进行测试的图像数据示例。

$imageDataInfoSample = "data:image/png;base64,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"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接