phpjavascripthtmlcanvasdata-url

html5 canvas toDataURL returns blank image


Beginning with a blank canvas:

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

Then initializing that 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;
  }

Then do a bunch of drawing on the canvas.

Then try to save it to the server using ajax and PHP on the backend.

On the client:

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

Take the resulting string, which is base64 encoded png, directly to PHP and and base64_decode() the string... The image is always the right size, but it has none of the drawing on it - just a transparent image. This doesn't seem to be an issue with base64_decode() in PHP, it seems to be a security thing or something. It fails in both Firefox 4 and the latest Chrome.

Dumping the resulting png image to firefox with "image/png" headers yields this in the error console:

Error: Image corrupt or truncated: http://somewhere.com/showimage.php
Source file: http://somewhere.com/showimage.php

But... The image isn't corrupt or truncated that I can tell unless toDataURL() is broken everywhere because the php stuff simply base64_decode() the result of toDataURL().

Any ideas?

Thanks!


Solution

  • Have you seen this comment in the PHP docs for 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);
    ?>