1

I tried to convert the image to base64 string using javascript/angularjs following the code showed on this stacko page, you can also check the code in detail here.

function toDataURL(src, callback, outputFormat) {
  var img = new Image();
  img.crossOrigin = 'Anonymous';
  img.onload = function() {
    var canvas = document.createElement('CANVAS');
    var ctx = canvas.getContext('2d');
    var dataURL;
    canvas.height = this.naturalHeight;
    canvas.width = this.naturalWidth;
    ctx.drawImage(this, 0, 0);
    dataURL = canvas.toDataURL(outputFormat);
    callback(dataURL);
  };
  img.src = src;
  if (img.complete || img.complete === undefined) {
    img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
    img.src = src;
  }
}

toDataURL(
  'https://www.gravatar.com/avatar/d50c83cc0c6523b4d3f6085295c953e0',
  function(dataUrl) {
    console.log('RESULT:', dataUrl)
  }
)

I call this function in the init inside the controller but when i load the page the image doesn't load the first time, but if i load the page again the image does load. I also made a button to call the function again, and as expected the image loads just fine after i load the page and press the button.

Debugging the code i found that the image only loads if it gets to the last if statement which, as by the detailed code, is flushing the cache. But since it's trying by the second time wouldn't this be the normal approach?

  if (img.complete || img.complete === undefined) {
    img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
    img.src = src;
  }

After getting here it goes on to img.onload and loads the image again, this time the image loads just fine.

What am i missing? Do i need to do something to wait the image to load? Can i do something to make it load later? Or is it something else?

Kaluk
  • 73
  • 2
  • 8
  • 1
    Just to make your end goal easier, what is the purpose of getting the base64 string? This seems highly likely to be a [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem), and addressing the _actual problem_ (e.g maybe you're trying to upload the image data from a URL) as opposed to the _attempted solution_ (converting it to base64 and sending the string) will be much more beneficial for you and for future readers. – Patrick Roberts Dec 03 '18 at 20:49
  • When asking a question about a problem caused by your code, you will get much better answers if you provide code people can use to reproduce the problem. That code should be… **Complete** – Provide all parts needed to reproduce the problem. See [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – georgeawg Dec 03 '18 at 20:55
  • I'm converting to base64 string to send it to a S3 bucket where i have to cut the image beforehand with the ui-cropper library. So when i upload the image, the image i have is the ImgPreview from the ui-cropper which in it's library is using the file reader instead of canvas. – Kaluk Dec 03 '18 at 20:57
  • 1
    Base64 strings add an extra 33% overhead. It is more efficient to send an image to a server in binary form. – georgeawg Dec 03 '18 at 20:58
  • @PatrickRoberts it turns out your advice helped me more than anything, taking another look at the problem from a different perspective and as you said i wasn't addressing the problem of the upload first. Thanks for the advice. – Kaluk Dec 05 '18 at 15:58
  • @Kaluk I'm glad to hear that. If it's convenient for you, you can [answer your own question](https://stackoverflow.com/help/self-answer) with the solution you ended up using, as long as you're detailed enough for future readers to be able to reproduce your results.This will earn you [reputation](https://stackoverflow.com/help/whats-reputation) to unlock more features on the site as a trusted user. – Patrick Roberts Dec 05 '18 at 16:01

1 Answers1

0

Turns out i wasn't addressing the fact that ImgPreview from ui-cropper can be used, therefore there wasn't any need to convert the image. I only made a $scope in the view to get that ImgPreview and send that to the database. Sadly i can't provide any code.

Kaluk
  • 73
  • 2
  • 8