1

I am following this example to save the canvas to a PNG file. http://greenethumb.com/article/1429/user-friendly-image-saving-from-the-canvas/

My problem: The downloaded file is corrupt and when I open it in notepad, it has this pattern:

  1. HTML CODE (Correspoding to the PHP file)
  2. ASCII CHARACTERS (which I thought corresponded to the PNG file)
  3. <body><html>

If I remove #1 and #3 and save the file locally, I get a valid PNG image.

I am doing exactly what the example above says, but my results are different. Why would the dataURL have any other info. other than the canvas itself?

Thanks.

Edit

<?php
$imdata = $_POST["imgdata"];
//run this code only when there is long POST data
if(strlen($imdata)>1000) {
        //removing the "data:image/png;base64," part
        $imdata =  substr($imdata,strpos($data,",")+1);
        // put the data to a file
        file_put_contents('image.png', base64_decode($imdata));
        //force user to download the image
        if(file_exists("image.png")){
                header('Content-type: image/png');
                header('Content-Disposition: attachment; filename="image.png"');
                readfile('image.png');
        }
}
?>
SEU
  • 1,304
  • 4
  • 15
  • 36
  • Even though you say "I am doing exactly what the example above says", it would be nice to see the exact code _you_ have, just to be able to rule out misunderstandings and typos. – Thorbear Aug 01 '12 at 14:13

2 Answers2

5

When you save the canvas in HTML5 you end up with a base64 string, at the start of this string is specific information about the image format. You will need to strip this off, if you wish to save the base64 for conversion to a hard file later. If you want to redraw the image onto a canvas (or some image control) you will need to prepend this information again.

Here's how you save your file:

var dataURL = document.getElementsByTagName("canvas")[0].toDataURL("image/png");

// strip off invalid data for saving
dataURL = dataURL.replace("data:image/png;base64,", ""); 

Now you can just convert your base64 string to an image and save to a hard file when you need to. If you want to display this image on a canvas again, here's how you do it:

function displayImage(base64string) {
    var canvas = document.getElementsByTagName("canvas")[0];
    var context = canvas.getContext("2d");
    var image = new Image();

    // prepend the required image info again
    image.src = "data:image/png;base64," + base64string;

    image.onload = function() {
        context.drawImage(image, 0, 0);
    }
}
Paul Aldred-Bann
  • 5,840
  • 4
  • 36
  • 55
  • 2
    I think this answer misses the point of the linked tutorial, which was to have a download-button for the user to download the image, and using PHP to generate a more human-friendly name for the file. – Thorbear Aug 01 '12 at 14:16
  • @Thorbear I agree, I don't directly answer the question. But what I have done is provided the means of extracting a usable base64 string from the canvas - this can then be used in code behind to produce an image object and return this to a user via HTTP as a download. – Paul Aldred-Bann Aug 01 '12 at 14:19
  • Ok. I would also like to mention that your solution is already covered in the linked tutorial, although they've solved it slightly differently: `data = data.substr(data.indexOf(',') + 1).toString();` – Thorbear Aug 01 '12 at 14:22
1

This worked for me -

function SaveCanvasToFile(myFileName) 
{
   var link = document.createElement('a');
   link.textContent = 'download image';
   link.href = myCanvas.toDataURL('image/png', 1.0);
   link.download = myFileName;
   document.body.appendChild(link);
   link.click();
   document.body.removeChild(link);    
}

This has the advantage that the file doesn't have to go to the server and then back down again.

k4mars
  • 11
  • 2
  • ... or you can hover over the canvas, press the right mouse button, and from the menu select 'save image as' (in Chrome and Firefox at least). – k4mars Feb 22 '19 at 21:03