111
<input type="file" id="asd"/>

I would like to get the image in base64 once the user chose that (before submitting the form)

Something like :

$(input).on('change',function(){
  var data = $(this).val().base64file(); // it is not a plugin is just an example
  alert(data);
});

I read about File API and other stuffs, I would like a simple and cross-browsers solution (IE6/IE7 excluded obviously)

Any help appreciated thanks.

10
  • 1
    And what did you not understand about the HTML5 File api? What did you try? What did not work? Commented Jul 17, 2013 at 21:03
  • @epascarello they are not fully supported actually caniuse.com/#feat=fileapi i need a work around, especially cause android versions are still used (old versions) as well as for old iOS versions, and i also would like to involve IE9 which is still used a lot :P
    – bombastic
    Commented Jul 17, 2013 at 21:04
  • a workaround for what? What are you trying to do with the file? base64file() - is that a plugin? Commented Jul 17, 2013 at 21:05
  • @David i just would like to get the base64 file once the user select the file from his pc, base64file() is just an example
    – bombastic
    Commented Jul 17, 2013 at 21:06
  • 1
    @epascarello yeah and that was exactly my question, how to support all browsers :D
    – bombastic
    Commented Jul 18, 2013 at 13:20

8 Answers 8

257

function readFile() {
  
  if (!this.files || !this.files[0]) return;
    
  const FR = new FileReader();
    
  FR.addEventListener("load", function(evt) {
    document.querySelector("#img").src         = evt.target.result;
    document.querySelector("#b64").textContent = evt.target.result;
  }); 
    
  FR.readAsDataURL(this.files[0]);
  
}

document.querySelector("#inp").addEventListener("change", readFile);
<input id="inp" type="file">
<p id="b64"></p>
<img id="img" height="150">

(P.S: A base64 encoded image (String) 4/3 the size of the original image data)

Check this answer for multiple images upload.

Browser support: http://caniuse.com/#search=file%20api
More info here: https://developer.mozilla.org/en-US/docs/Web/API/FileReader

7
  • 2
    yep thank you, so actually i can see File reader is no fully supported, how can i make the same supporting also old android/iOS devices ?
    – bombastic
    Commented Jul 18, 2013 at 6:30
  • 2
    are there any other browsers? xD
    – RicardoE
    Commented Mar 25, 2014 at 23:47
  • That was really neat code for image to base64 conversion.. Can I be able to convert this back into image in javascript? I've used base64 encode decode before, but dont have any idea about image conversions..
    – The Coder
    Commented Feb 11, 2015 at 15:01
  • 1
    @TheCoder You can put it right into img src as base64 string, to get image data out of it, use canvas context.
    – Qwerty
    Commented May 16, 2016 at 1:02
  • 1
    @bombastic I used JS to build both iOS and android app on both platform they worked fine. The iOS is normal and on android, i had needed some native code to get permission to gallery... Commented Jun 17, 2019 at 8:41
38

Exactly what you need:) You can choose callback version or Promise version. Note that promises will work in IE only with Promise polyfill lib.You can put this code once on a page, and this function will appear in all your files.

The loadend event is fired when progress has stopped on the loading of a resource (e.g. after "error", "abort", or "load" have been dispatched)

Callback version

        File.prototype.convertToBase64 = function(callback){
                var reader = new FileReader();
                reader.onloadend = function (e) {
                    callback(e.target.result, e.target.error);
                };   
                reader.readAsDataURL(this);
        };

        $("#asd").on('change',function(){
          var selectedFile = this.files[0];
          selectedFile.convertToBase64(function(base64){
               alert(base64);
          }) 
        });

Promise version

    File.prototype.convertToBase64 = function(){
         return new Promise(function(resolve, reject) {
                var reader = new FileReader();
                reader.onloadend = function (e) {
                    resolve({
                      fileName: this.name,
                      result: e.target.result, 
                      error: e.target.error
                    });
                };   
                reader.readAsDataURL(this);
        }.bind(this)); 
    };

    FileList.prototype.convertAllToBase64 = function(regexp){
      // empty regexp if not set
      regexp = regexp || /.*/;
      //making array from FileList
      var filesArray = Array.prototype.slice.call(this);
      var base64PromisesArray = filesArray.
           filter(function(file){
             return (regexp).test(file.name)
           }).map(function(file){
             return file.convertToBase64();
           });
      return Promise.all(base64PromisesArray);
    };

    $("#asd").on('change',function(){
      //for one file
      var selectedFile = this.files[0];
      selectedFile.convertToBase64().
          then(function(obj){
            alert(obj.result);
          });
      });
      //for all files that have file extention png, jpeg, jpg, gif
      this.files.convertAllToBase64(/\.(png|jpeg|jpg|gif)$/i).then(function(objArray){
            objArray.forEach(function(obj, i){
                  console.log("result[" + obj.fileName + "][" + i + "] = " + obj.result);
            });
      });
    })

html

<input type="file" id="asd" multiple/>
3
  • This method will give errors when applied to the program that use Angular though since Angular cannot tolerate File.prototype.convertToBase64 = function(){..} and FileList.prototype.convertAllToBase64 = function(regexp){...} Commented Mar 3, 2022 at 18:39
  • Thnx) you can rewrite it to angular service... Commented Mar 4, 2022 at 22:55
  • The method by @N3K0100183 can be modified to work in typescript file for Angular platform though. Commented Mar 5, 2022 at 17:07
15
<input type="file" onchange="getBaseUrl()">
function getBaseUrl ()  {
    var file = document.querySelector('input[type=file]')['files'][0];
    var reader = new FileReader();
    var baseString;
    reader.onloadend = function () {
        baseString = reader.result;
        console.log(baseString); 
    };
    reader.readAsDataURL(file);
}
4
  • 1
    'file' is declared but its value is never read inside the getBaseUrl() function.
    – Biranchi
    Commented Jan 4, 2018 at 3:07
  • 1
    @Biranchi file is used in the last line reader.readAsDataURL(file);
    – Achim
    Commented Apr 11, 2020 at 6:44
  • This method is working even the program that use Angular even though the way to define file variable need to be changed according to the program writing style. Commented Mar 3, 2022 at 18:45
  • 2
    👍 I wish I could upvote this answer twice 😅 for effectiveness and simplicity. Commented Nov 24, 2022 at 19:45
7

It's useful to work with Deferred Object in this case, and return promise:

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

And above function could be used in this way:

var inputElement = $("input[name=file]");
readImage(inputElement).done(function(base64Data){
    alert(base64Data);
});

Or in your case:

$(input).on('change',function(){
  readImage($(this)).done(function(base64Data){ alert(base64Data); });
});
1
  • i really needed this, i mean the deferred since i am returning the base64 to calling method. I want to know if your solution will work in all browsers ?
    – Thameem
    Commented Apr 8, 2020 at 11:04
1

Function convert image to base64 using jquery (you can convert to vanila js). Hope it help to you!

Usage: input is your nameId input has file image

<input type="file" id="asd"/>
<button onclick="proccessData()">Submit</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>

async function converImageToBase64(inputId) {
  let image = $('#'+inputId)[0]['files']

  if (image && image[0]) {
    const reader = new FileReader();

    return new Promise(resolve => {
      reader.onload = ev => {
        resolve(ev.target.result)
      }
      reader.readAsDataURL(image[0])
    })
  }
}

async function proccessData() {
  const image = await converImageToBase64('asd')
  console.log(image)
}

</script>

Example: converImageToBase64('yourFileInputId')

https://codepen.io/mariohandsome/pen/yLadmVb

0

For modern Browsers (no IE support)

Html file input

<style>
.upload-button {
  background-color: grey;
}

.upload-button input{
  display:none;
}
</style>
<label for="upload-photo" class="upload-button">
    Upload file
    <input
     type="file"
     id="upload-photo"
    </input>
</label>

JS

document.getElementById("upload-photo").addEventListener("change", function({target}){
 if (target.files && target.files.length) {
      try {
        const uploadedImageBase64 = await convertFileToBase64(target.files[0]); 
        //do something with above data string 
      } catch() {
        //handle error
      }
    }
})

function convertFileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = reject;
  });
}
-1

// https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL

/* Simple */
function previewImage( image, preview, string )
{

    var preview     = document.querySelector( preview );
    var fileImage   = image.files[0];

    var reader      = new FileReader();

    reader.addEventListener( "load", function() {

        preview.style.height    = "100";
        preview.title           = fileImage.name;

        // convert image file to base64 string
        preview.src             = reader.result;

        /* --- */

        document.querySelector( string ).value = reader.result;                    

    }, false );

    if ( fileImage )
    {
        reader.readAsDataURL( fileImage );
    }

}

document.querySelector( "#imageID" ).addEventListener( "change", function() {

    previewImage( this, "#imagePreviewID", "#imageStringID" );

} )
/* Simple || */
<form>

    File Upload: <input type="file" id="imageID" /><br />
    Preview: <img src="#" id="imagePreviewID" /><br />    
    String base64: <textarea id="imageStringID" rows="10" cols="50"></textarea>

</form>

codesanbox

-1
  const FR = new FileReader();
    
  FR.addEventListener("load", function(evt) {
    document.querySelector("#img").src         = evt.target.result;
    document.querySelector("#b64").`textContent` = evt.target.result;
  }); 
    
  FR.readAsDataURL(this.files[0]);
  
< img id="inp" src="https://tlc.ca/pricing-tool/images/logo.png">
<p id="b64"></p>
<img id="img" height="150">
  • List item
2
  • 1
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Feb 10, 2023 at 13:46
  • 1
    You just copied the accepted answer and added stuff without explaining, how is this useful?
    – tyzion
    Commented Jun 14, 2023 at 10:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.