112
<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 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 Commented Jul 17, 2013 at 21:06
  • 1
    @epascarello yeah and that was exactly my question, how to support all browsers :D Commented Jul 18, 2013 at 13:20

8 Answers 8

258

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

Sign up to request clarification or add additional context in comments.

7 Comments

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 ?
are there any other browsers? xD
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..
@TheCoder You can put it right into img src as base64 string, to get image data out of it, use canvas context.
@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...
|
39

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 Comments

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){...}
Thnx) you can rewrite it to angular service...
The method by @N3K0100183 can be modified to work in typescript file for Angular platform though.
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 Comments

'file' is declared but its value is never read inside the getBaseUrl() function.
@Biranchi file is used in the last line reader.readAsDataURL(file);
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.
👍 I wish I could upvote this answer twice 😅 for effectiveness and simplicity.
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 Comment

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 ?
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

Comments

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

Comments

-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

Comments

-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 Comments

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.
You just copied the accepted answer and added stuff without explaining, how is this useful?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.