2

I'm working on a project which involves a user dragging and dropping boxes onto a div to create a layout. Once the user is done, there's a button to press which takes the div and creates a canvas element from it using html2canvas, then it opens up in a new window as an image. This is fine, but I need it to save somewhere so it can be attached to an email and sent. So far, all I have is the base64 encoded string which I cannot really do anything with.

On the js side, I have:

html2canvas($('#canvas')).then(function(canvas) {
    $('canvas').addClass('canvas-layout');
    var src = canvas.toDataURL();
    var output=src.replace(/^data:image\/(png|jpg);base64,/, "");
    $.post( 'result.php', { data: output })
        .done( function(response) {
            console.log(response);
        }
    );
    return false;
});

where #canvas is the ID of the div. In the result.php file, I have:

$decodedData = base64_decode($_POST['data']);

$img = $decodedData;

$image = fopen($img, 'r');
file_put_contents("images/layout.png", $image);
fclose($image);

But I get a warning saying that I'm passing a string to fopen() - though this solution was given in another stackoverflow post and people seemed to get this working. Originally, the js just opened the image in a new window like so:

window.open(src,'Image','width=1440,height=650,resizable=1');

But the URL in the browser window is the base64 encoded string which I can't do anything with.

Is there a way of doing what I want to achieve?

Thanks

Michael Emerson
  • 1,774
  • 4
  • 31
  • 71
  • could you show the post where you got this php code? I'm pretty confident that `$img` is not `$decodedData` in it. http://php.net/manual/en/function.fopen.php – Kaiido Mar 22 '16 at 13:01
  • http://stackoverflow.com/a/8848250/5194337 - although there is perhaps something else I need to do in order to correctly encode the image before it's passed to the ajax file? – Michael Emerson Mar 22 '16 at 14:26
  • The most effective and versatile solution would be to just send `canvas.toDataURL()` from JavaScript as it is. Then replace the PHP part with a call to [PHP-FileUpload](https://github.com/delight-im/PHP-FileUpload/tree/master) and its [`DataUriUpload`](https://github.com/delight-im/PHP-FileUpload/blob/7c950635cbd45ade9fb2656eb285259dc2a8f0fb/src/DataUriUpload.php) component which does all the heavy lifting and allows for much more control and means of validation. It’s [documented here](https://github.com/delight-im/PHP-FileUpload/blob/master/README.md#data-uri-uploads). – caw Dec 06 '17 at 11:33

1 Answers1

1

OK - I've got it sorted. Basically, I needed to trim some other data off the string before being able to write it.

So, I added this code before file_put_contents :

$img = $_POST['data']; // Using the raw encoded string
$img = str_replace('data:image/png;base64,', '', $img); // removed unnecessary string
$img = str_replace(' ', '+', $img);
$data = base64_decode($img); // then decoded it
$file = "images/layout-file_". uniqid().".png"; // define new image name
$success = file_put_contents($file, $data); // finally write to server

This way it generates a uniquely named file and does not corrupt.

Michael Emerson
  • 1,774
  • 4
  • 31
  • 71