1

I've been using this code to download images from a canvas:

function fileSave1() 
{
    var dataURL = "";
    var canvasSave = document.getElementById("cSave");
    if (document.getElementById("png").checked == true) dataURL = canvasSave.toDataURL(); // PNG is default 
    if (document.getElementById("jpg").checked == true) dataURL = canvasSave.toDataURL('image/jpeg', Number(document.getElementById("quality").value) / 100); // JPG with Quality Setting requires 2 arguments 
    //var start = dataURL.indexOf(";"); //start point will vary based on image/png (9 characters) vs image/jpeg (10 characters) 
    //dataURL = dataURL.slice(start); 
    //dataURL = "data:application/octet-stream" + dataURL; 
    if (document.getElementById("jpg").checked == true) document.getElementById("afterCanvas2").innerHTML = '<a download="new_image.jpg" href='+ dataURL +'>Save New JPG with a Quality Setting of ' + document.getElementById("quality").value + ' </a>';
    if (document.getElementById("png").checked == true) document.getElementById("afterCanvas2").innerHTML = '<a download="new_image.png" href='+ dataURL +'>Save New Full Quality PNG</a>';
}

However, in Chrome, it is not downloading some PNGs and very high quality JPGs. This post suggests the problem is that the file sizes are too large, and suggests canvas.toBlob() as the workaround. This post has a code sample, but I am having trouble adapting it to my code.

I would deeply appreciate assistance with the proper syntax.

Thank you

EDIT: The code that failed:

        function fileSave1()
        {

            var canvas = document.getElementById('cSave');

            canvas.toBlob(function(blob)
            {
                var url = URL.createObjectURL(blob);
                url.onload = function() 
                {
                    URL.revokeObjectURL(url);
                };

            });

          document.getElementById("afterCanvas2").innerHTML = '<a download="new_image.png" href='+ url +'>Save New Full Quality PNG</a>';    

        }

Error: Uncaught ReferenceError: url is not defined at fileSave1.

Thank you

TonyLuigiC
  • 185
  • 1
  • 2
  • 13
  • "...`canvas.toBlob()` as the workaround...I am having trouble adapting it to my code." I agree, using a blob might fix it. Can we see the code you wrote to do that? – Sidney Jan 22 '18 at 22:42
  • I already deleted it. Let me see if I can undo the delete in Notepad++. – TonyLuigiC Jan 22 '18 at 22:56
  • @Sidney A power surge closed Notepad++, I have re-written the code and added it to the original post as an edit. Thanks! – TonyLuigiC Jan 22 '18 at 23:15
  • I suggest changing the topic to "Canvas.toDataURL() not downloading some PNGs and very high quality JPGs" since that is the issue. Canvas.toBlob() is the fix, but it's not working at all. – TonyLuigiC Jan 23 '18 at 00:24

1 Answers1

2

I'm curious why you're trying to attach an onload handler to the URL in the second code snippet? That's not part of the accepted answer from the post you linked.

It looks like the second code snippet almost works, but there are a few things out of place.

I believe this will work:

function fileSave1() {
  var canvas = document.getElementById('cSave');

  canvas.toBlob(function(blob) {
    const anchor = document.createElement('a')
    const url = URL.createObjectURL(blob)
    anchor.href = url
    anchor.download = 'canvas.png'
    document.body.appendChild(anchor)
    anchor.click()
    document.body.removeChild(anchor)
    URL.revokeObjectURL(url)
  }, 'image/png')
}

Notice that it click()'s the anchor element as soon as the blob is ready, so calling the function fileSave1() will immediately download the file, instead of adding an anchor to the document for the user to click. You could change this behavior if you want.

Sidney
  • 4,495
  • 2
  • 18
  • 30