Hay mucho escrito sobre las ventajas de usar imágenes en Base64, y URLs data en general: Ahorran solicitudes al servidor, y por lo tanto aceleran la carga de la página. Pero por otra parte, hacen menos legible el código, así que hay que encontrar un equilibrio.

Pero ese no es el tema principal de este artículo, sino cómo conseguir transformar fácilmente (sin necesidad de servidor siquiera), las imágenes en base64.

La forma es fácil, y es con la API HTML5 window.FileReader.

Demo

Una forma fácil sería hacer algo como:

<input type="file" id="foto">

<script>(function(){

if( ! window.FileReader ) {
	return; // No soportado
}
var input = document.querySelector('#foto');
// Éste es el elemento mediante el que el usuario nos indica cuál es la imagen

// No hacen falta hacks para IE, ya que IE 7 y 8 ya se habrán caído con la condición anterior
input.addEventListener('change', function(e){
	// Cogemos el primer archivo
	var archivo = input.files[0],
		// Creamos la instancia de FileReader
		reader = new FileReader(),
		urlBase64;
	// Os esperábais algo más complicado?
	reader.onload = function(){
		urlBase64 = reader.result;
		// Hacer lo que se quiera con la url
	}
	reader.readAsDataUrl(file);
}, false);

})()
</script>

¿Fácil, no?

Para darle una utilidad, he construido una pequeña aplicación para que podáis transformar vuestras imágenes a Base64 (aunque en verdad podéis transformar cualquier tipo de archivo):

Demo

16 pensamientos en “FileReader y cómo transformar imágenes a Base64 sin subirlas a ningún sitio

  1. Bitacoras.com
  2. Imagen de AlejandroAlejandro el dijo:

    Hola no se mucho de javascript, como puedo imprimir el código en la pantalla?
    Hice esto y no me funciona…

    
    <input type="file" id="foto">
    
    <script>
    (function(){if( ! window.FileReader ) {	return; // No soportado}
    var input = document.querySelector('#foto');
    // Éste es el elemento mediante el que el usuario nos indica cuál es la imagen
    // No hacen falta hacks para IE, ya que IE 7 y 8 ya se habrán caído con la condición anterior
    input.addEventListener('change', function(e){	// Cogemos el primer archivo
    	var archivo = input.files[0],
    		// Creamos la instancia de FileReader
    		reader = new FileReader(),
    		urlBase64;	// Os esperábais algo más complicado?
    	reader.onload = function(){
    		urlBase64 = reader.result;
    		// Hacer lo que se quiera con la url
    		document.write(urlBase64);
    	}
    	reader.readAsDataUrl(file);
    }, false);
    })()</script>
    
    • Imagen de Emilio Cobos Álvarez el dijo:

      El problema es que el el FileReader es asíncrono. Si lo que quieres hacer es mostrar el código debajo del input cuando el usuario cambie el archivo, lo ideal sería:

      <input type="file" id="foto">
      <div id="result"><!-- Aquí aparecerá el resultado --></div>
      <script>
      (function(){
      if( ! window.FileReader ) {	return; // No soportado}
      var input = document.querySelector('#foto'),
      	resultDiv = document.querySelector('#result');
      
      // Éste es el elemento mediante el que el usuario nos indica cuál es la imagen
      // No hacen falta hacks para IE, ya que IE 7 y 8 ya se habrán caído con la condición anterior
      input.addEventListener('change', function(e){	// Cogemos el primer archivo
      	var archivo = input.files[0],
      		// Creamos la instancia de FileReader
      		reader = new FileReader(),
      		urlBase64;	// Os esperábais algo más complicado?
      	reader.onload = function(){
      		urlBase64 = reader.result;
      		// Hacer lo que se quiera con la url
      		result.innerHTML = urlBase64;
      	}
      	reader.readAsDataUrl(file);
      }, false);
      })()</script>
  3. Imagen de anaana el dijo:

    Bravo Emilio!!!

    Gracias mil.
    Perdón mi ignorancia. No entiendo en dónde tendría que poner el código de la foto en el código que diste arriba. Me encantaría usarlo.
    Saludos

  4. Imagen de TortuguicaTortuguica el dijo:

    Estoy desarrollando mi proyecto fin de ciclo y la verdad es que me encuentro paralizado en un punto que está muy relacionado con tu post, Emilio, así que vaya mi agradecimiento por el mismo de antemano ;-) Pero voy a aprovechar la ocasión, jeje, para preguntarte si se te ocurre cómo se podría enviar esa imagen que hemos guardado al servidor, como si fuera un archivo. Es que no quiero utilizar un input de tipo fyle, aunque sospecho que al final no tendré otra elección. En fin, si se te ocurriera algo sería genial. Un saludo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Puedes usar las siguientes etiquetas y atributos HTML:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre data-language=""> <ul> <ol> <li>
Para poner código usa <pre data-language="[lenguaje]"><code>[código]</code></pre>, y no olvides escapar el HTMl.