Please tell me why when we use the function Canvas.toDataURL (); and draw simple shapes on the canvas, such as Bezier curves. I get a working reference in base 64 format.

<canvas id="myCanvas" width="578" height="200" style="display:none;"></canvas> <img id="canvasImg" alt="Right click to save me!"> <script> var canvas = document.getElementById('myCanvas'); var context = canvas.getContext('2d'); // draw cloud context.beginPath(); context.moveTo(170, 80); context.bezierCurveTo(130, 100, 130, 150, 230, 150); context.bezierCurveTo(250, 180, 320, 180, 340, 150); context.bezierCurveTo(420, 150, 420, 120, 390, 100); context.bezierCurveTo(430, 40, 370, 30, 340, 50); context.bezierCurveTo(320, 5, 250, 20, 250, 50); context.bezierCurveTo(200, 5, 150, 20, 170, 80); context.closePath(); context.lineWidth = 5; context.fillStyle = '#8ED6FF'; context.fill(); context.strokeStyle = '#0000ff'; context.stroke(); // save canvas image as data url (png format by default) var dataURL = canvas.toDataURL(); // set canvasImg image src to dataURL // so it can be saved as an image document.getElementById('canvasImg').src = dataURL; </script> 

But as soon as I try to upload a picture a white screen opens. And the base64 url ​​does not change when changing different pictures. It changes only when the width and height of the canvas element changes. Which suggests that the picture is simply not drawn on the canvas, although it is visible in the browser. How to be?

 <a id="img"><p>Download</p></a> <canvas id="can" width="600" height="300"></canvas> <script> var example = document.getElementById('can'); ctx = example.getContext('2d'); pic = new Image(); pic.onload = function() { ctx.drawImage(pic, 0, 0); } pic.src = '1.jpg'; var canvas = document.getElementById('can'); var dataURL = canvas.toDataURL("image/png"); document.getElementById('img').href = dataURL; document.write(dataURL); </script> 

Tell me, maybe I incorrectly draw the picture on the canvas. And if such a way to get a link to the picture can not be, tell me an effective way, anyone will do, even the slowest and cumbersome.

    1 answer 1

    Firstly, because the operation is asynchronous, and you are exporting a white canvas.

    It is necessary so:

     var example = document.getElementById('can'); ctx = example.getContext('2d'); pic = new Image(); pic.onload = function() { ctx.drawImage(pic, 0, 0); var canvas = document.getElementById('can'); var dataURL = canvas.toDataURL("image/png"); document.getElementById('img').href = dataURL; } pic.src = "https://www.google.ru/images/srpr/logo11w.png"; 

    Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

    I think this will not happen if the picture is loaded from your own site.

    But still there is a problem. Data uri has a length limit.

    • This is brilliant: D, it works, after 13 hours I got to the answer. Thank! Everything was so simple - KiZZek
    • At the expense of limiting the length, is it possible to divide a large image into 4 parts, get 4 different data url? And then collect using php or js, the only question is how? - KiZZek
    • @KiZZek, there was something about blob uri, but I don't remember. I think it is worth in that direction. - Qwertiy