How to convert image into base64 string using javascript

Go To StackoverFlow.com

390

I need to convert my image to a base64 string so that i can send my image to a server. Is there any js file for this... ? Else how to convert it

2011-05-27 09:26
by Coder_sLaY
Where does your image come from - TJHeuvel 2011-05-27 09:28
http://stackoverflow.com/questions/934012/get-image-data-in-javascrip - duri 2011-05-27 09:36
JS and jQ: http://stackoverflow.com/questions/17710147/jquery-js-get-input-file-image-in-base64-encode - Roko C. Buljan 2014-12-22 22:34


154

You can use the HTML5 <canvas> for it:

Create a canvas, load your image into it and then use toDataURL() to get the base64 representation (actually, it's a data: URL but it contains the base64-encoded image).

2011-05-27 09:36
by ThiefMaster
Does toDataURL give control over the callbacks such as done/fail/always as is the case for xhr - Jeroen 2014-02-04 22:34
Can we extract 2 or more canvas as a single PNG - techie_28 2016-07-11 11:48
Can you please make a jsbin or at least write some code here - vsync 2016-11-04 15:52
This approach fails in the case of CORS violation. Apart from that, this solution should address the question - Revanth Kumar 2017-04-04 19:01
Here is npm package for ituser3517175 2018-10-09 14:56


686

There are multiple approaches you can choose from:

1. Approach: FileReader

Load the image as blob via XMLHttpRequest and use the FileReader API to convert it to a dataURL:

function toDataURL(url, callback) {
  var xhr = new XMLHttpRequest();
  xhr.onload = function() {
    var reader = new FileReader();
    reader.onloadend = function() {
      callback(reader.result);
    }
    reader.readAsDataURL(xhr.response);
  };
  xhr.open('GET', url);
  xhr.responseType = 'blob';
  xhr.send();
}

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

This code example could also be implemented using the WHATWG fetch api:

const toDataURL = url => fetch(url)
  .then(response => response.blob())
  .then(blob => new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onloadend = () => resolve(reader.result)
    reader.onerror = reject
    reader.readAsDataURL(blob)
  }))


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

These approaches:

  • lack in browser support
  • have better compression
  • work for other file types as well

Browser Support:


2. Approach: Canvas

Load the image into an Image-Object, paint it to a non tainted canvas and convert the canvas back to a dataURL.

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)
  }
)

in detail

Supported input formats:

image/png, image/jpeg, image/jpg, image/gif, image/bmp, image/tiff, image/x-icon, image/svg+xml, image/webp, image/xxx

Supported output formats:

image/png, image/jpeg, image/webp(chrome)

Browser Support:


3. Approach: Images from the local file system

If you want to convert images from the users file system you need to take a different approach. Use the FileReader API:

function encodeImageFileAsURL(element) {
  var file = element.files[0];
  var reader = new FileReader();
  reader.onloadend = function() {
    console.log('RESULT', reader.result)
  }
  reader.readAsDataURL(file);
}
<input type="file" onchange="encodeImageFileAsURL(this)" />

2013-11-29 11:46
by HaNdTriX
+1 for img.crossOrigin = 'Anonymous';amirnissim 2014-01-19 16:00
didn't work in IE11 for m - Dmitry 2014-04-29 06:14
Are you sure you are using IE11? I just tested it in IE11 and it worked fine for me. But I also tested it in IE10 and I got a security error because IE10 doesn't support CORS for images. You might have to proxy your images through your own domain in order to make it work in IE10 - HaNdTriX 2014-04-29 08:01
worked well on Chrom - Marcelo Teixeira Ruggeri 2014-05-03 02:53
When i try to use this the GIF image will still say this in itsbase64 form: data:image/png;base64................

they should say image/gif. I tried passing image/gif in outputFormat var variable by getting the image format but still it shows data:image/png...Why is this so - maths 2014-06-12 01:52

The GIF format is not supported as an output format. More info @ https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement#Methods (I updated my answer to clarify this point - HaNdTriX 2014-06-12 08:24
Is there a way to do this without jquery as the callback - Doge 2014-07-07 10:37
This function has nothing to do with jQuery. This is an async operation so you need a callback or some kind of promise - HaNdTriX 2014-07-07 11:55
Not working in chrome for me: Image from origin **** has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access.DickieBoy 2014-08-05 09:19
What version of chrome are you using? Did you try the fiddle above - HaNdTriX 2014-08-05 13:34
@DickieBoy It depends on the configuration of the server hosting the image. The JSFiddle works with the image http://upload.wikimedia.org/wikipedia/commons/4/4a/Logo2013Google.png because its server has allowed fiddle.jshell.net access. Read more at http://stackoverflow.com/questions/10636611/how-does-access-control-allow-origin-header-wor - Fuhrmanator 2014-08-09 13:01
@Fuhrmanator I tried the fiddle. That was the error I got, could be that the server has changed its configuration - DickieBoy 2014-08-12 09:03
Ah the fickle world of development, seems to work now - DickieBoy 2014-08-12 10:21
Just in case this trips anyone else up, this routine includes the "data:image/jpg;base64," header in the string it returns, so you don't need to append that - Chris Rae 2015-01-16 21:02
@Chris R Thanks for pointing that out. I admit the function name was not as descriptive, as it should have been - HaNdTriX 2015-01-16 22:23
Also, if you try to create a very large canvas on iOS (e.g. one from the camera, in my case) this will appear to work fine but return "data:,". You can fix this by changing the canvas width and height to something smaller, e.g. 100, and modifying the read call to something like ctx.drawImage(img, 0, 0, 100, 100) - Chris Rae 2015-01-21 20:35
is this lossless? like, same as base64encode(fileget_contents($url)) of PHP? or will the canvas conversion mess with it - hanshenrik 2015-03-06 02:25
This script won't work follow HTTP 301 Mover Permanently Location: http://new/location.jpg ; should fix that or add a warning. that's (probably) why the code example above isn't working for people, they don't change the url, and that url now redirects to http://upload.wikimedia.org/wikipedia/commons/4/4a/Logo2013Google.pn - hanshenrik 2015-03-06 02:29
Warnin2: something messes with the content. somewhere along the way, there's a chance the data gets corrupted/altered (even though, perhaps not by much), at least that happens for me on firefox 35 on some images, the base64 is different from the base64 that php creates on the same image - hanshenrik 2015-03-06 02:39
Yes that is right. Some data might get lost since we actually draw the image to a canvas Element (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage) and then convert it to a dataURL (https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL) - HaNdTriX 2015-03-06 09:12
Is there a way to make this work for image saved on a local file system e.g. file://C:/test.jpglexith 2015-06-23 10:34
No thats not possible, because you won't have access to the local file system. But you can use the fileReader API. Check out this fiddle http://jsfiddle.net/handtrix/xztfbx1m - HaNdTriX 2015-06-23 10:57
How second approach could support file type? - DaNeSh 2015-11-11 21:48
@DaNeSh You could encode videos or audio files as well as image files. e.g.: http://jsfiddle.net/handtrix/YvQ5y/1730 - HaNdTriX 2015-11-12 14:28
Approach: FileReader (2) works more quickly than approach Canvas. Tested on big photos. Hope it will be helpfull for some one - Max 2015-12-24 06:07
Try this image! Not working https://qph.is.quoracdn.net/main-thumb-t-309833-200-3fIVdqGbgAIn8d5LaTub5mBWPsKkd2iC.jpe - asingh 2016-03-22 11:02
Yepp thats because it is blocked by the server via CORS. http://www.html5rocks.com/en/tutorials/cors - HaNdTriX 2016-03-22 12:15
If someone wants to use ES6 try this gist: https://gist.github.com/HaNdTriX/bdffd11761701fbeba27f23e9a69515 - HaNdTriX 2016-03-29 19:44
I was using approach 1 but had to comment out the "img.crossOrigin = 'Anonymous';" line in order to make it work in IE (11). I was getting 302 errors from IIS and all the images I was trying to download were reported as "Aborted" in the network tab of the IE Developer Console - breez 2016-03-30 10:58
FYI: IE11 throws InvalidStateError upon setting responseType. Workaround: Set responseType after calling open() for this to work in IE11. https://connect.microsoft.com/IE/feedback/details/795580/ie11-xmlhttprequest-incorrectly-throws-invalidstateerror-when-setting-responsetyp - Jeff Ward 2017-01-31 23:31
Thanks for letting me know! I have updated the answer - HaNdTriX 2017-02-02 11:10
For canvas rendering using this.width and this.height will give you the image size as fitted in the rendered element but if the image itself is larger it will result in only part of the image being rendered on the canvas. To fix this you can use this.naturalHeight and this.naturalWitdth instea - anyab 2017-06-26 11:01
Good catch @anyab! Thanks! I improved the answer - HaNdTriX 2017-07-02 22:00
@HaNdTriX Hi, could you explain why judge 'img.complete === undefined'?It is for compatibility - SmallTown NE 2018-01-29 07:06
This makes sure, that the load event also fires for cached images. https://gist.github.com/HaNdTriX/770463 - HaNdTriX 2018-01-29 07:22
If the complete api is not supported it will be undefined - HaNdTriX 2018-01-30 08:31
@HaNdTriX .. Can you give a code, for the same using axios..? I am working with reactjs - ArunValaven 2018-03-19 12:25
No, but here is a hint to point you in the right direction. Use axios responseType prop. - HaNdTriX 2018-03-21 12:51


68

This snippet could convert your string,image and even video file to base64 string data. Try it once...

<input id="inputFileToLoad" type="file" onchange="encodeImageFileAsURL();" />
<div id="imgTest"></div>
<script type='text/javascript'>
  function encodeImageFileAsURL() {

    var filesSelected = document.getElementById("inputFileToLoad").files;
    if (filesSelected.length > 0) {
      var fileToLoad = filesSelected[0];

      var fileReader = new FileReader();

      fileReader.onload = function(fileLoadedEvent) {
        var srcData = fileLoadedEvent.target.result; // <--- data: base64

        var newImage = document.createElement('img');
        newImage.src = srcData;

        document.getElementById("imgTest").innerHTML = newImage.outerHTML;
        alert("Converted Base64 version is " + document.getElementById("imgTest").innerHTML);
        console.log("Converted Base64 version is " + document.getElementById("imgTest").innerHTML);
      }
      fileReader.readAsDataURL(fileToLoad);
    }
  }
</script>

2014-05-15 05:20
by NoName
Not only is it great, this also bypasses the crossdomain origin problem! With this, you can allow users to supply their own images or images from an URL (since Windows will fetch it on its own), draw them on the canvas, and work with them while still being able to use .toDataURL() etc. Thanks a lot - ElDoRado1239 2014-11-16 16:35
Thanks! This works very well - Andrei 2016-10-28 19:59
Thanks for saving my days! - pankaj khanduja - Game Changer 2017-12-10 12:56
Hello, how can this be applied to an image loaded from a remote url without facing cross domain issues? Thank - guthik 2018-07-17 15:12


18

Here is what i did

//Author James Harrington 2014
function base64(file, callback){
  var coolFile = {};
  function readerOnload(e){
    var base64 = btoa(e.target.result);
    coolFile.base64 = base64;
    callback(coolFile)
  };

  var reader = new FileReader();
  reader.onload = readerOnload;

  var file = file[0].files[0];
  coolFile.filetype = file.type;
  coolFile.size = file.size;
  coolFile.filename = file.name;
  reader.readAsBinaryString(file);
}

And here is how you use it

base64( $('input[type="file"]'), function(data){
  console.log(data.base64)
})
2015-01-30 19:21
by James Harrington
what is btoa? : - Alexander Mills 2017-03-31 20:08
a = ASCII and b = Binary http://stackoverflow.com/questions/33854103/why-were-javascript-atob-and-btoa-named-like-that#answer-3385412 - James Harrington 2017-04-11 18:55
Why the downvote - James Harrington 2018-02-20 03:19
This is perfect. Nice job - J-Roel 2018-06-19 23:08


13

Basically, if your image is

<img id='Img1' src='someurl'>

then you can convert it like

var c = document.createElement('canvas');
var img = document.getElementById('Img1');
c.height = img.naturalHeight;
c.width = img.naturalWidth;
var ctx = c.getContext('2d');

ctx.drawImage(img, 0, 0, c.width, c.height);
var base64String = c.toDataURL();
2017-07-23 14:46
by mecek
Unfortunately this will only work for local images, if you try it useing a remote image (choose one from the web) it writes this to (firefox) console: 'SecurityError: The operation is insecure' - user2677034 2018-01-23 21:15
It may work on other images but depends on the CORS settings of that site and must be specified as <img id='Img1' src='someurl' crossorigin='anonymous'>Mike 2018-12-15 11:01


5

If you have a file object this simple function will work:-

function getBase64 (file,callback) {

    const reader = new FileReader();

    reader.addEventListener('load', () => callback(reader.result));

    reader.readAsDataURL(file);
}

Usage Ex:-

getBase64(fileObjectFromInput, function(base64Data){
    console.log("base 64 of file is",base64Data);//here you can have your code which uses base64 for its operation,//file to base64 by oneshubh
});
2018-12-09 17:25
by Shubham


4

You could use FileAPI, but it's pretty much unsupported.

2011-05-27 09:34
by Artem Tikhomirov


4

As far as i know image can be converted into base64 string either by FileReader() or storing it in canvas element and then use toDataURL() to get image.I had the simmilar kind of problem you can refer this.

Convert an image to canvas that is already loaded

2014-10-25 11:02
by Ajeet Lakhani


4

Try This code

File upload Chnage event ccall this function

  $("#fileproof").on('change', function () {
                readImage($(this)).done(function (base64Data) { $('#<%=hfimgbs64.ClientID%>').val(base64Data); });
            });


function readImage(inputElement) {
    var deferred = $.Deferred();

    var files = inputElement.get(0).files;

    if (files && files[0]) {
        var fr = new FileReader();
        fr.onload = function (e) {
            deferred.resolve(e.target.result);
        };
        fr.readAsDataURL(files[0]);
    } else {
        deferred.resolve(undefined);
    }

    return deferred.promise();
}

Store base64data in hidden filed to use.

2018-02-28 13:04
by ravi polara


0

Well, if you are using dojo, it gives us direct way to encode or decode into base64.

Try this:

To encode an array of bytes using dojox.encoding.base64:

var str = dojox.encoding.base64.encode(myByteArray);

To decode a base64-encoded string:

var bytes = dojox.encoding.base64.decode(str);
2013-08-29 14:01
by Vikash Pandey
@DownVoter - Dear its better to point out error also if you are marking something negative. so that someone can improve. as far as I am understanding dojo in also an JavaScript library then if you are allowed to use dojo, you can definitely use this approach - Vikash Pandey 2017-10-09 08:52