Immagine convertita in Base64


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

Vorrei ottenere l'immagine in base64 una volta che l'utente lo ha scelto (prima di inviare il modulo)

Qualcosa di simile a :

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

Ho letto di File API e altre cose, vorrei una soluzione semplice e cross-browser (IE6 / IE7 esclusi ovviamente)

Qualsiasi aiuto apprezzato grazie.


1
E cosa non hai capito dell'API File HTML5? Cosa hai provato? Cosa non ha funzionato?
epascarello

@epascarello non sono completamente supportati in realtà caniuse.com/#feat=fileapi ho bisogno di una soluzione, soprattutto perché le versioni di Android sono ancora utilizzate (vecchie versioni) così come per le vecchie versioni di iOS, e vorrei anche coinvolgere IE9 che è ancora molto usato: P
ampolloso

una soluzione alternativa per cosa? Cosa stai cercando di fare con il file? base64file()- è un plugin?
David Hellsing

@David vorrei solo ottenere il file base64 una volta che l'utente seleziona il file dal suo pc, base64file () è solo un esempio
bombastico

1
@epascarello yeah e questa era esattamente la mia domanda, come supportare tutti i browser: D
ampolloso

Risposte:


212

function readFile() {
  
  if (this.files && this.files[0]) {
    
    var FR= new FileReader();
    
    FR.addEventListener("load", function(e) {
      document.getElementById("img").src       = e.target.result;
      document.getElementById("b64").innerHTML = e.target.result;
    }); 
    
    FR.readAsDataURL( this.files[0] );
  }
  
}

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

( PS: un'immagine con codifica base64 (stringa) 4/3 della dimensione dei dati dell'immagine originale)

Controlla questa risposta per il caricamento di più immagini .

Supporto browser: http://caniuse.com/#search=file%20api
Maggiori informazioni qui: https://developer.mozilla.org/en-US/docs/Web/API/FileReader


2
sì grazie, quindi in realtà posso vedere che il lettore di file non è completamente supportato, come posso rendere lo stesso supporto anche ai vecchi dispositivi Android / iOS?
ampolloso

1
ci sono altri browser? xD
RicardoE

Quello era un codice davvero accurato per la conversione da immagine a base64 .. Posso essere in grado di riconvertirlo in immagine in javascript? Ho già utilizzato la decodifica della codifica base64, ma non ho idea delle conversioni di immagini ..
The Coder

@TheCoder Puoi metterlo direttamente in img src come stringa base64, per ottenere dati di immagine da esso, usa il contesto canvas.
Qwerty

1
@bombastic Ho usato JS per creare sia app iOS che Android su entrambe le piattaforme che hanno funzionato bene. L'iOS è normale e su Android avevo bisogno di un codice nativo per ottenere l'autorizzazione alla galleria ...
Osman Gani Khan Masum

35

Esattamente quello che ti serve :) Puoi scegliere la versione di richiamata o la versione Promessa. Nota che le promesse funzioneranno in IE solo con Promise polyfill lib. Puoi inserire questo codice una volta in una pagina e questa funzione apparirà in tutti i tuoi file.

L'evento loadend viene attivato quando l'avanzamento del caricamento di una risorsa viene interrotto (ad esempio, dopo l'invio di "errore", "interruzione" o "caricamento")

Versione di richiamata

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

Versione promessa

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

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

1
'file' viene dichiarato ma il suo valore non viene mai letto all'interno della funzione getBaseUrl ().
Biranchi

@Biranchi fileè usato nell'ultima rigareader.readAsDataURL(file);
Achim

7

È utile lavorare con Deferred Object in questo caso e restituire la promessa:

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

E la funzione sopra potrebbe essere utilizzata in questo modo:

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

O nel tuo caso:

$(input).on('change',function(){
  readImage($(this)).done(function(base64Data){ alert(base64Data); });
});

ne avevo davvero bisogno, intendo il differito poiché sto restituendo il base64 al metodo di chiamata. Voglio sapere se la tua soluzione funzionerà con tutti i browser?
Thameem

0

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.