Desarrolladores: Trucos semanales

Convertir imágenes a base64

Prueba ahora LinkedIn Learning sin cargo y sin compromiso.

Prueba gratis Mostrar modalidades de suscripción
Aprende los mejores trucos y tips, y descubre los conceptos básicos indispensable para todo desarrollador web, independientemente de tu experiencia. Si ya llevas desarrollando por años o si vienes del mundo del diseño y jamás has tocado una sola línea de código, todo lo que aprenderás con esta serie semanal de trucos serán una gran adición a tu actividad profesional y apuntalará tus habilidades como programador o desarrollador. Descubre desde increíbles consejos para que puedas tratar con tu cliente y saber cómo cobrar adecuadamente, hasta cuestiones técnicas claves para organizar y gestionar mejor tu tiempo y proyectos desarrollando.
10:13
  Añadir a marcadores

Transcripción

Trabajar con imágenes puede ser la cosa más simple del mundo o la más complicada, pero sin duda es una de las tareas que más retos nos pone en el camino. Uno de estos retos es cuando estás trabajando con fotografías de usuarios o logos de algún producto y deseas guardarlos en una base de datos. Para hacer esto existen dos caminos. El primero es subir la imagen de forma tradicional y guardar solamente la referencia de la misma en el campo adecuado de nuestro modelo. El otro camino es cuando deseamos guardar la imagen en su totalidad dentro de la base de datos, pero ¿hablas en serio? ¿Guardar la imagen directamente en la base de datos? ¿Es eso posible? La respuesta del millón es sí, sí es posible. Lo único que debemos hacer es transformar la imagen a tal forma que podemos guardarla en la base de datos y que coincida con el tipo de dato que estamos usando. Para esto existe la codificación en Base64 que ofrece JavaScript. Solo ten cuidado de no confundirte y uses los métodos de codificación para cadenas de texto que existen. La codificación a Base64 que usaremos para este propósito, se basa en el uso del canvas de HTML5. Pues, es este componente el que nos permitirá hacer la exportación a Base64 de la imagen y poder guardarla en una base de datos, y así usarla posteriormente. Hagamos un ejercicio sobre cómo convertir una imagen a Base64. En este caso, vamos a revisar dos alternativas que existen para poder hacer esta conversión. Una de ellas basados en el canvas y el otro basado en Archivo. Para que esto pueda funcionar adecuadamente, tenemos ya una base de este código completamente hecha que tú vas a poder utilizar en tus proyectos. Para esto, podemos revisar en el archivo Index.html. Tenemos una sección donde va una imagen, en este caso, una división que se llama imgB64. Quiere decir que nosotros ahorita en este ejercicio vamos a inyectar la imagen directamente como Base64 en esta división y, posteriormente, vamos a utilizar un input de tipo "archivo" para poder cargar una imagen, ¿cuál? La que nosotros deseemos y poderla convertir también a Base64. Para esto, tenemos ya un par de métodos explicados en este ejercicio. Vamos a revisar rápidamente el primero. El primero se llama fromCanvasToBase64. Es decir, vamos a utilizar el canvas para convertirlo a Base64. Recibirá una URL, es decir, la ubicación de la imagen, que puede ser local o puede ser remota. Tiene un callback, este callback es el que me va a retornar un valor, obviamente con un formato de salida. Para esto yo tengo aquí listo una función que me invoca a una fotografía llamada fog.jpg. Y aquí mismo yo ya tengo listo el callback de esta función, que es lo que me va a regresar, la función fromCanvasToBase64. Lo que me va a regresar va a ser, tal cual, el archivo ya convertido a esta base. Veamos rápidamente como funciona. Lo primero que hacemos es crear una imagen, posteriormente vamos a establecer un crossOrigin como anónimo para que no tengamos ningún problema a la hora de pasar los archivos. Después de esto, vamos a hacer una carga de la imagen, es decir, la instancia que estamos haciendo de una imagen tiene un método llamado onload. Este método onload me va a permitir trabajar y poder cargar cosas. En este caso, vamos a generar aquí adentro un canvas. Este canvas nunca lo vamos a instanciar nosotros a la pantalla y que se "renderee", simplemente lo vamos a estar trabajando como un objeto tras bambalinas directamente con JavaScript. Una vez que lo tenemos establecemos el contexto de 2D para poder dibujar, establecemos un ancho y un alto y, posterior a esto, hacemos el dibujado. Es decir, se está tomando la imagen y se está pintando directamente en el canvas. Una vez que tenemos esto ya pintado, podemos utilizar el método toDataURL, que me va a permitir a mí extraer la información. Esta información que se va a extraer yo la voy a guardar tal cual en una variable llamada outputFormat, y voy a poder regresarla como un resultado de mi callback. Así entonces, esto va a ser el resultado que yo voy a obtener y es lo que voy a estar pintando. Aquí en primera instancia lo estoy mandando a la consola. Es decir, ya se "parseó" toda la fotografía o toda la imagen que necesitaba. Y una vez que quedó "parseada" por completo, yo la voy a mostrar en la consola. También la voy a mostrar directamente en pantalla. Para esto yo estoy creando aquí una nueva imagen, que es un elemento que genero de manera dinámica. Y posterior a esto voy a asignar a su propiedad SRC el valor de base64Img. Cuando yo lo asigno, simplemente lo voy a guardar y esto lo va a leer. Es decir, va a leer el valor de Base64 y va a interpretar toda la imagen sin ningún problema. Y simplemente lo último que hacemos es asignarlo al elemento HTML que nosotros teníamos acá definido, que es esta división. Vamos a probarlo. Esto debe de ejecutarse tan pronto cargue la página. Así que vamos a nuestro navegador y ejecutémoslo. Ahora, no olvides que debes estar en un entorno cliente-servidor, si no la aplicación no va a funcionar adecuadamente. Listo, nosotros ya actualizamos nuestra página, y vemos cómo inmediatamente esto ya se pudo plasmar en pantalla. Lo que tomó un poco más de tiempo de dibujarse fue la función en la consola. Esto pues tiene que dibujar todos estos textos que es un texto bastante, bastante amplio para definir lo que es esta imagen. Por tanto, tomó bastante tiempo, y se imprime en la consola, pero eso no impidió que se pudiera dibujar adecuadamente. Ahora, la otra forma que tenemos de hacerlo es a través de un archivo. Esto funcionará de la siguiente forma. Yo puedo seleccionar aquí un archivo. Vamos a seleccionar esta imagen que se llama "amsterdam". La selecciono, doy Abrir, y automáticamente se agrega. Eso parece un comportamiento transparente y sin ningún problema, pero ¿qué está sucediendo realmente? Primero, veamos que el procesamiento para la consola seguía trabajando un poco y eso atoró e hizo un poco más lento el procesamiento del navegador. Lo que sucedió por acá es que tenemos nosotros listo tal cual toda la Base64 que representa esta imagen. Vamos a revisar el código. Esta función se llama fromFileToBase64. Si nosotros tenemos el archivo index.html, vamos a poder revisar que tenemos un input que se llama avatar de tipo "archivo", y que acepta solo imágenes. Y esto, cuando detecta que hay un cambio, ejecuta el método fromFileToBase64. Vamos de regreso a JavaScript, y lo primero que vamos a hacer va a ser comentar la función que estábamos utilizando hace unos momentos para que esto no nos entorpezca lo que vamos a ver nosotros de resultado en la consola. Ahora, esta función, fromFileToBase64, lo primero que hace es tomar la referencia del input que tiene el archivo. A partir de esto, nosotros preguntamos si hay archivos o no hay archivos a través de la propiedad length. Si hay archivos, entonces podemos entrar y "parsear" todo lo que sucede adentro. Aquí nosotros podemos acceder a cada uno de los archivos que se tienen, como solo se seleccionó uno, entonces accedemos al nivel cero. Ahora, vamos a crear una instancia de un objeto llamado FileReader. FileReader es un objeto que va a manejar archivos; y este FileReader como tal me va a permitir hacer una carga. Entonces, yo voy a indicar que haga una carga de algo. ¿De qué? De lo que yo estaré levantando con mis archivos. En este caso, lo que yo voy a estar trabajando será el archivo que estoy cargando. Así, cuando lo carga y lo "parsea" ya lo va a cargar en Base64. Es decir, aquí ya viene, y lo vamos a guardar en la función srcData. Quiere decir que aquí ya mi imagen quedó guardada de esta manera. Pero ahora, ten cuidado, porque realmente ahorita esta función no se ha invocado. Esa función se va a invocar hasta acá en la línea 44, pues tenemos este mismo fileReader. Y vamos a mandarle a la opción readAsDataURL. Y lo que le vamos a mandar de parámetro será el archivo fileToLoad, que es tal cual el archivo que venía en el objeto de input que nosotros seleccionamos. Una vez que nosotros ya tenemos ese objeto, lo mandamos, y el objeto fileReader va a ejecutar su método onload. Aquí es entonces donde ya existe el evento y donde hace la carga; y cuando lo carga, lo carga como Base64. Después lo demás es algo mecánico igual a lo demás que habíamos hecho. Se genera un elemento de HTML en forma de imagen, se asigna el valor srcData, que es el contenido en Base64, a la propiedad src o source de la nueva imagen. Después de esto, simplemente lo vamos a pintar en HTML y vamos a mostrarlo en la consola. Vamos a guardar y vamos a probar nuevamente. Ahora que yo actualizo, ya no me va a aparecer ninguna imagen de inicio, porque yo comenté esa invocación que tenía que ver con el canvas. Ahora queda simplemente esto. Pulso el botón Seleccionar archivo, seleccionamos una fotografía, en este caso amsterdam, abrimos, y listo, tenemos la imagen. Y de este lado, en la consola tenemos tal cual toda la Base64 que se ha generado. Si te pudiste dar cuenta, generar la Base64 utilizando el objeto fileReader, es muchísimo más rápido y eficaz que trabajar tal cual con el objeto toDataURL que maneja el canvas. Por lo cual, trabajar con este tipo de objetos, FileReader, es muchísimo más óptimo que con el canvas. Ahora yo puedo cambiar la fotografía. Vamos a elegir la fotografía de fog, que es la que se pintaba anteriormente, y también, entonces, voy a tener listo todo lo que yo quiera imprimir en pantalla. Ahora sí, podemos tener una cadena de texto muy grande, en este caso, porque es una fotografía bastante amplia y bastante pesada, pero que me va a permitir guardar si así lo deseo todo un string ya sea en un archivo o en una base de datos.