Snowman
Snowman

Reputation: 47

Wrong base64 from canvas

Try a couple of days to solve one problem, but I can not understand why it is impossible. In canvas pictures drawn but the derivation gives wrong base64. I did not understand why. I just started, and didn't have great experience javascript. Help a newbie who can.

HTML:

<canvas id="canvas" width="400" height="300"></canvas> <textarea id="base64" rows="10" cols="80"></textarea> <img id="image">

JAVASCRIPT

function loadImages(sources, callback) { var images = {}; var loadedImages = 0; var numImages = 0; for(var src in sources) { numImages++; } for(var src in sources) { images[src] = new Image();
images[src].onload = function() {
  if(++loadedImages >= numImages) {
    callback(images);
  } };
images[src].src = sources[src];}} var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); var sources = { a: 'http://www.prairiedogmag.com/wp-content/uploads/2012/08/Cute-Animals-office-bat-4-200x300.jpg',   b: 'http://worldnewspress.net/wp-content/uploads/2014/03/happiest-animals-all-time-18-200x300.jpg' }; loadImages(sources, function(images) { context.fillStyle = "red"; context.fillRect(0, 0, 400, 300);  context.drawImage(images.a, 0, 0, 200, 300); context.drawImage(images.b, 201, 0, 200, 300); });  var url = document.getElementById('base64').value =document.getElementById('canvas').toDataURL(); document.getElementById('image').src = url;

Upvotes: 0

Views: 905

Answers (1)

markE
markE

Reputation: 105015

To execute the context.toDataURL method any images drawn on the canvas must originate from the same domain as the web page code.

If not, you fail cross-domain security and the browser will refuse to do .toDataURL.

It looks like you are pulling cross-domain images and therefore failing this security concern.

Check out CORS security:

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

Here's example working code and a Demo: http://jsfiddle.net/m1erickson/76xF3/

This example fetches images from a server that's configured to deliver images in a cross-domain compliant way. There are multiple configuration adjustments that must be done on the server. Also notice the code: crossOrigin="anonymous". That's the code on the client side that allows cross-origin images (the server must be configured properly first).

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var context=canvas.getContext("2d");

    var imageURLs=[];  // put the paths to your images here
    var imagesOK=0;
    var imgs=[];
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/character1.png");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/character3.png");
    loadAllImages(start);

    function loadAllImages(callback){
        for (var i=0; i<imageURLs.length; i++) {
            var img = new Image();
            img.crossOrigin="anonymous";
            imgs.push(img);
            img.onload = function(){ 
                imagesOK++; 
                if (imagesOK>=imageURLs.length ) {
                    callback();
                }
            };
            img.onerror=function(){alert("image load failed");} 
            img.src = imageURLs[i];
        }      
    }

    function start(){

        // the imgs[] array now holds fully loaded images
        // the imgs[] are in the same order as imageURLs[]

        context.fillStyle = "red"; 
        context.fillRect(0,0,120,110);  
        context.drawImage(imgs[0], 0, 0, 60, 110); 
        context.drawImage(imgs[1], 60, 0, 60, 110); 
        var url = document.getElementById('base64').value =canvas.toDataURL(); 
        document.getElementById('image').src = canvas.toDataURL();

    }


}); // end $(function(){});
</script>
</head>
<body>
    <h4>The canvas</h4>
    <canvas id="canvas" width=120 height=110></canvas>
    <h4>The image created from the canvas .toDataURL</h4>
    <img id="image">
    <h4>The base64 encoded image data</h4>
    <textarea id="base64" rows="10" cols="80"></textarea>
</body>
</html>

Upvotes: 1

Related Questions