Php 将画布图像保存到服务器

Php 将画布图像保存到服务器,php,jquery,html,html5-canvas,Php,Jquery,Html,Html5 Canvas,我从数据库中提取了数据,创建了一个HTML表,我希望能够将其保存为服务器上的PNG 当我使用PHP将PNG保存到服务器时,它是空的 我创建了静态代码(即不是来自数据库)来说明我的示例 如果我手动右键单击图像并另存为,则该图像将正确保存,只有当我尝试将其自动化时,该图像才为空白。我在Chrome和Firefox上都试过,结果都一样 如果有人能帮我纠正我做错的任何事情,我将不胜感激。多谢各位 我正在使用: PHP 7.3.4 jQuery 3.4.1 铬76.0.3809.100 Firefox

我从数据库中提取了数据,创建了一个HTML表,我希望能够将其保存为服务器上的PNG

当我使用PHP将PNG保存到服务器时,它是空的

我创建了静态代码(即不是来自数据库)来说明我的示例

如果我手动右键单击图像并另存为,则该图像将正确保存,只有当我尝试将其自动化时,该图像才为空白。我在Chrome和Firefox上都试过,结果都一样

如果有人能帮我纠正我做错的任何事情,我将不胜感激。多谢各位

我正在使用:

  • PHP 7.3.4
  • jQuery 3.4.1
  • 铬76.0.3809.100
  • Firefox 68.01
index.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="jquery-3.4.1.min.js" type="text/javascript"></script>
</head>

<body>
    <div id="invoicetable">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <style>
        body        {font-family: courier new; font-size: 13px; }
        td      {padding: 2px 5px 2px 5px; }
        .headerTD   {font-weight: bold; }
        .w60        {width: 60px; }
        .w80        {width: 80px; }
        .w100       {width: 100px; }
        .w120       {width: 120px; }
        .w160       {width: 160px; }
            </style>

<table class='' border='01' style='border-collapse: collapse; font-size: 14px; font-family: trebuchet ms; '><tr><td class='headerTD w100'>Date</td><td class='headerTD w60'>Type</td><td class='headerTD w160'>Detail</td><td class='headerTD w120'>Username</td><td class='headerTD w100'>Line</td><td class='headerTD w100'>Start Date</td><td class='headerTD w100'>End Date</td><td class='headerTD w80'>Subtotal</td></tr><tr><td>23/07/2019</td><td>Credit</td><td>Business Fibre 1</td><td>abc@def.com</td><td>011122223333</td><td>23/07/2019</td><td>21/08/2019</td><td>&pound; <div style='float: right'>-7.74</div></td></tr><tr><td>04/08/2019</td><td>Charge</td><td>Business Fibre 1</td><td>ghi@jkl.com</td><td>01234567890</td><td>04/08/2019</td><td>03/09/2019</td><td>&pound; <div style='float: right'>22.50</div></td></tr><tr><td>04/08/2019</td><td>Charge</td><td>Line Rental</td><td></td><td>01234567890</td><td>04/08/2019</td><td>03/09/2019</td><td>&pound; <div style='float: right'>15.66</div></td></tr><tr><td>04/08/2019</td><td>Charge</td><td>Line Rental</td><td></td><td>01234567890</td><td>04/07/2019</td><td>03/08/2019</td><td>&pound; <div style='float: right'>0.00</div></td></tr><tr><td colspan='7'></td><td>&pound; <div style='float: right'>30.42</div></td></tr></table>

        </div>
    </div>
    <br>
    <br>

    <canvas id="canvas" width="930" height="150"></canvas>

    <script>
        $(function() {
            var canvas = document.getElementById("canvas");
            var ctx = canvas.getContext("2d");
            var imgW = 930;
            var imgH = 150;
            ctx.fillStyle = "white";
            ctx.fillRect(0, 0, imgW, imgH);

            var data = "<svg xmlns='http://www.w3.org/2000/svg' width='" + imgW + "' height='" + imgH + "'>" + "<foreignObject width='100%' height='100%'>" + $("#invoicetable").html() + "</foreignObject>" + "</svg>";
            var DOMURL = self.URL || self.webkitURL || self;
            var img = new Image();
            var svg = new Blob([data], {
                type: "image/svg+xml;charset=utf-8"
            });
            var url = DOMURL.createObjectURL(svg);
            img.onload = function() {
                ctx.drawImage(img, 0, 0);
                DOMURL.revokeObjectURL(url);
            };
            img.src = url;

            var canvas = document.getElementById("canvas");
            var pngData = canvas.toDataURL("image/png");
            $.post("savepng.php", {
                pngData: pngData
            }, function(data) {});

        });
    </script>
</body>

</html>
<?php
$aaa = explode(",", $_POST['pngData']);
file_put_contents("invoicedata.png", base64_decode($aaa[1]));
?>

正文{字体系列:courier new;字体大小:13px;}
td{padding:2px 5px 2px 5px;}
.headerTD{字体大小:粗体;}
.w60{宽度:60px;}
.w80{宽度:80px;}
.w100{宽度:100px;}
.w120{宽度:120px;}
.w160{宽度:160px;}
DateTypeDetailUserName开始日期结束日期小计2009年7月23日Credit业务光纤1abc@def.com01112222333323/2019年8月7日,英镑-7.7404/08/2019计费业务光纤1ghi@jkl.com0123456789004/2019年9月8日&2019年9月8日£;22.5004/08/2019收费线租金0123456789004/08/201903/09/2019英镑;15.6604/08/2019收费线租金0123456789004/07/201903/08/2019英镑;0.00英镑;30.42


$(函数(){ var canvas=document.getElementById(“canvas”); var ctx=canvas.getContext(“2d”); var-imgW=930; var-imgH=150; ctx.fillStyle=“白色”; ctx.fillRect(0,0,imgW,imgH); var data=“”+”+$(“#invoicetable”).html(); var DOMURL=self.URL | | self.webkitURL | | self; var img=新图像(); var svg=新的Blob([data]{ 类型:“image/svg+xml;charset=utf-8” }); var url=DOMURL.createObjectURL(svg); img.onload=函数(){ ctx.drawImage(img,0,0); revokeObjectURL(url); }; img.src=url; var canvas=document.getElementById(“canvas”); var pngData=canvas.toDataURL(“image/png”); $.post(“savepng.php”{ pngData:pngData },函数(数据){}); });

savepng.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="jquery-3.4.1.min.js" type="text/javascript"></script>
</head>

<body>
    <div id="invoicetable">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <style>
        body        {font-family: courier new; font-size: 13px; }
        td      {padding: 2px 5px 2px 5px; }
        .headerTD   {font-weight: bold; }
        .w60        {width: 60px; }
        .w80        {width: 80px; }
        .w100       {width: 100px; }
        .w120       {width: 120px; }
        .w160       {width: 160px; }
            </style>

<table class='' border='01' style='border-collapse: collapse; font-size: 14px; font-family: trebuchet ms; '><tr><td class='headerTD w100'>Date</td><td class='headerTD w60'>Type</td><td class='headerTD w160'>Detail</td><td class='headerTD w120'>Username</td><td class='headerTD w100'>Line</td><td class='headerTD w100'>Start Date</td><td class='headerTD w100'>End Date</td><td class='headerTD w80'>Subtotal</td></tr><tr><td>23/07/2019</td><td>Credit</td><td>Business Fibre 1</td><td>abc@def.com</td><td>011122223333</td><td>23/07/2019</td><td>21/08/2019</td><td>&pound; <div style='float: right'>-7.74</div></td></tr><tr><td>04/08/2019</td><td>Charge</td><td>Business Fibre 1</td><td>ghi@jkl.com</td><td>01234567890</td><td>04/08/2019</td><td>03/09/2019</td><td>&pound; <div style='float: right'>22.50</div></td></tr><tr><td>04/08/2019</td><td>Charge</td><td>Line Rental</td><td></td><td>01234567890</td><td>04/08/2019</td><td>03/09/2019</td><td>&pound; <div style='float: right'>15.66</div></td></tr><tr><td>04/08/2019</td><td>Charge</td><td>Line Rental</td><td></td><td>01234567890</td><td>04/07/2019</td><td>03/08/2019</td><td>&pound; <div style='float: right'>0.00</div></td></tr><tr><td colspan='7'></td><td>&pound; <div style='float: right'>30.42</div></td></tr></table>

        </div>
    </div>
    <br>
    <br>

    <canvas id="canvas" width="930" height="150"></canvas>

    <script>
        $(function() {
            var canvas = document.getElementById("canvas");
            var ctx = canvas.getContext("2d");
            var imgW = 930;
            var imgH = 150;
            ctx.fillStyle = "white";
            ctx.fillRect(0, 0, imgW, imgH);

            var data = "<svg xmlns='http://www.w3.org/2000/svg' width='" + imgW + "' height='" + imgH + "'>" + "<foreignObject width='100%' height='100%'>" + $("#invoicetable").html() + "</foreignObject>" + "</svg>";
            var DOMURL = self.URL || self.webkitURL || self;
            var img = new Image();
            var svg = new Blob([data], {
                type: "image/svg+xml;charset=utf-8"
            });
            var url = DOMURL.createObjectURL(svg);
            img.onload = function() {
                ctx.drawImage(img, 0, 0);
                DOMURL.revokeObjectURL(url);
            };
            img.src = url;

            var canvas = document.getElementById("canvas");
            var pngData = canvas.toDataURL("image/png");
            $.post("savepng.php", {
                pngData: pngData
            }, function(data) {});

        });
    </script>
</body>

</html>
<?php
$aaa = explode(",", $_POST['pngData']);
file_put_contents("invoicedata.png", base64_decode($aaa[1]));
?>

这是预期的图像输出:

您的代码有三个问题:

  • 您试图在将SVG图像绘制到画布之前保存图像。
    将图像保存在
    onload
    回调中

  • 似乎您从问题中提取了代码,但没有修复问题,因此在调用
    toDataURL
    时,您会收到一个关于受污染画布的错误

  • 如果使用上一个问题中的修复程序,则呈现磅符号时似乎出现问题。这似乎是编码的一个问题,修复方法是

  • 要解决这些问题,请使用以下代码:

    var img = new Image();
    img.onload = function() {
        ctx.drawImage(img, 0, 0);
    
        var canvas = document.getElementById("canvas");
        var pngData = canvas.toDataURL("image/png");
        $.post("savepng.php", {
            pngData: pngData
        }, function(data) {});
    };
    function buildSvgImageUrl(svg) {
        var b64 = window.btoa(unescape(encodeURIComponent(svg)));
        return "data:image/svg+xml;base64," + b64;
    }
    img.src = buildSvgImageUrl(data);
    

    toDataURL
    在以下
    数据前面加上前缀:image/png;base64,
    。您需要在服务器上解码之前删除它。@Leetylor他正在删除它。非常感谢gre_gor,我确实没有添加更正。现在一切都好了。再次感谢:-)