Search code examples
javascripthtmlhtml5-canvaslocal-storagedata-uri

DataURL not returning value


I have created a function that stores DataURI of image in local storage.

Data is stored perfectly in the local storage but if I try to get value from function i.e. return statement, then I get "undefined" value. Probably, the function is returning value before even converting to dataURL.

Need your help.

Here is my code:

function getImageDataURL(local_name,w,h,i){    
var data, canvas, ctx;
var img = new Image();
img.onload = function(){      
    canvas = document.createElement('canvas');
    canvas.width = w;
    canvas.height = h;
    ctx = canvas.getContext("2d");
    ctx.drawImage(img,0,0,w,h);
    try{
        data = canvas.toDataURL("image/png");
        localStorage.setItem(local_name,data);
    }catch(e){
        console.log("error "+e)
    }
}
try{
    img.src = i;
}catch(e){}
return data;

}


Solution

  • The problem is that you're taking an asynchronous value and trying to return it synchronously. img.onload is being called way after the function returns. A common pattern in JavaScript is to pass the function another function to call when its done:

    function getImageDataURL(local_name, w, h, i, callback) {    
        var data, canvas, ctx;
        var img = new Image();
        img.onload = function (){      
            canvas = document.createElement('canvas');
            canvas.width = w;
            canvas.height = h;
            ctx = canvas.getContext("2d");
            ctx.drawImage(img,0,0,w,h);
    
            callback(canvas.toDataURL("image/png"));
        }
        img.src = i;
    }
    
    getImageDataURL('image', 100, 100, 'image.png', function (data) {
        localStorage.setItem(local_name, data);
        console.log(data);
    });
    

    One problem you might run into is a cross-domain security feature. If you draw an image from a foreign domain (that is, one that's different from the page with the JavaScript), it will "taint" the canvas, and you're no longer able to access the image data using toDataURL.

    To bypass this, you'll either need to get the remote server to implement CORS approval or run a proxy server so it looks like the image is coming from your own server.