I'm trying hard to accomplish and understand the following 'monstercode' that I wrote. Basically, this function should fire when the File input dialog (HTML) was fired. But the code goes well only a few lines. It loads the image, and then in the first alert() it shows me the base64 of the original image, but then, later in the code, when the actual image should be loaded in a canvas, it returns (in another alert()) height 0, probably meaning that the image wasn't loaded correctly or at all.
The HTML input form (simplified) looks like this:
<input type='File' accept='image/*' onChange='changeBtn(this);' /> And the function below:
function changeBtn(elem) { selfile = document.getElementById(elem.id); if ('files' in selfile) { var file = selfile.files[0]; if ('name' in file) { str1 = file.name; } if ('size' in file) { str1 += ' (' + ((file.size / 1024) / 1024).toFixed(2) + 'MB)'; } document.getElementById("label_" + elem.id).innerHTML = str1; var FR= new FileReader(); var img = document.createElement("img"); FR.onload = function(e) { img.src = e.target.result; alert(e.target.result); // Returns B64 of the original image }; FR.readAsDataURL(file); var canvas = document.createElement('canvas'); var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0); var MAX_WIDTH = 800; var MAX_HEIGHT = 600; var width = img.width; var height = img.height; alert(height); // Returns 0 if (width > height) { if (width > MAX_WIDTH) { height *= MAX_WIDTH / width; width = MAX_WIDTH; } } else { if (height > MAX_HEIGHT) { width *= MAX_HEIGHT / height; height = MAX_HEIGHT; } } canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, width, height); var dataurl = canvas.toDataURL("image/png"); alert(dataurl); // Returns only "data; " and nothing more } } Thanks in advance for any help. Seems quite simple, but I don't get it. I rewrote the code at least 3 times, but I get always the same result.
img. You define it, then use it outside ofonloadwhere it is still empty.FR.readAsDataURL(file);which will complete by issuing the callback to onload. HoweverFR.readAsDataURL(file);returns immediately and continues executing your code whether theimgvariable got set up or not. If you move all the code that followsFR.readAsDataURL(file);inside the onload, it should work. It may not be the best way to do it but it is a start.FR.readAsDataURL(file);inside the onload, it should work." - Code operating outside of a callback when it should be inside is not a scoping issue? :) When OP usesimgforimg.widthandimg.heightit's still operating as a new<img>, so the width and height are 0. Inside the callback, this would be different.readAsDataURL()should stay outside the callback. Everything after that should go inside.