Coming long after, but none of the answers here are entirely correct.
When drawn on a canvas, the passed image is uncompressed + all pre-multiplied.
When exported, its uncompressed or recompressed with a different algorithm, and un-multiplied.
All browsers and devices will have different rounding errors happening in this process
(see Canvas fingerprinting).
So if one wants a base64 version of an image file, they have to request it again (most of the time it will come from cache) but this time as a Blob.
Then you can use a FileReader to read it either as an ArrayBuffer, or as a dataURL.
function toDataURL(url, callback){_x000D_
var xhr = new XMLHttpRequest();_x000D_
xhr.open('get', url);_x000D_
xhr.responseType = 'blob';_x000D_
xhr.onload = function(){_x000D_
var fr = new FileReader();_x000D_
_x000D_
fr.onload = function(){_x000D_
callback(this.result);_x000D_
};_x000D_
_x000D_
fr.readAsDataURL(xhr.response); // async call_x000D_
};_x000D_
_x000D_
xhr.send();_x000D_
}_x000D_
_x000D_
toDataURL(myImage.src, function(dataURL){_x000D_
result.src = dataURL;_x000D_
_x000D_
// now just to show that passing to a canvas doesn't hold the same results_x000D_
var canvas = document.createElement('canvas');_x000D_
canvas.width = myImage.naturalWidth;_x000D_
canvas.height = myImage.naturalHeight;_x000D_
canvas.getContext('2d').drawImage(myImage, 0,0);_x000D_
_x000D_
console.log(canvas.toDataURL() === dataURL); // false - not same data_x000D_
});
_x000D_
<img id="myImage" src="https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png" crossOrigin="anonymous">_x000D_
<img id="result">
_x000D_