Skip to content
Back to Blog

Imagen a Base64: Data URIs Hechos Correctamente

Un data URI base64 te permite embeber una imagen directamente en HTML o CSS sin solicitudes HTTP extra. Esta guía muestra la sintaxis exacta data:image, la penalización de tamaño del 33% a considerar y cuándo no es recomendable.

SZ
Founder, Molixa
13 min read
Compartir
Imagen a Base64: Data URIs Hechos Correctamente
Table of contents10 sections

Convertir una imagen a base64 transforma un archivo binario en una larga cadena ASCII que puedes pegar directamente en HTML, CSS, JSON o una columna de base de datos. Esa cadena se convierte en una URI de datos como data:image/png;base64,iVBORw0KGgo..., y el navegador la renderiza como si cargara un archivo de imagen real. El detalle que la mayoría de las páginas convertidoras nunca mencionan: base64 hace que cada imagen sea aproximadamente un 33% más grande, por lo que incrustar es una herramienta que se usa en casos específicos, no por defecto.

Esta guía muestra la sintaxis exacta, el prefijo MIME correcto para cada formato, cómo codificar una imagen en el navegador y en código, y las matemáticas de almacenamiento en caché que determinan si incrustar una imagen determinada es una decisión inteligente o un error.

¿Qué es una URI de datos de imagen Base64?#

Una URI de datos es una forma de incrustar el contenido de un archivo directamente dentro de un documento, en lugar de enlazar a un archivo externo. Para las imágenes, el formato es fijo y predecible:

data:[<tipo MIME>][;base64],<datos codificados>

Un ejemplo real de PNG se ve así (truncado):

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJ...

Tres partes importan:

  • data: le dice al navegador que esto son datos en línea, no una URL a buscar.
  • image/png;base64 es el tipo MIME más el indicador de codificación. Esta es la parte que la gente suele equivocar.
  • Todo después de la coma son los bytes codificados en base64 de la imagen real.

Debido a que la imagen completa vive dentro de la cadena, el navegador no realiza una solicitud de red separada para ella. Esa única propiedad es la razón de ser de las URI de datos y la fuente de todas las ventajas y desventajas de este artículo.

Modelo mental rápido: base64 no es compresión. Es lo contrario. Es una forma de representar datos binarios usando solo caracteres de texto seguros, y esa representación siempre es más grande que la original.

El prefijo MIME por formato de imagen#

Usar el tipo MIME incorrecto es la razón número uno por la que una imagen incrustada se muestra como un icono roto. El prefijo debe coincidir con los bytes reales del archivo, no con la extensión de archivo que crees tener.

Formato de imagenPrefijo correcto de URI de datos
PNGdata:image/png;base64,
JPEGdata:image/jpeg;base64,
GIFdata:image/gif;base64,
WebPdata:image/webp;base64,
SVGdata:image/svg+xml;base64,
ICO (favicon)data:image/x-icon;base64,

Ten en cuenta que JPEG es image/jpeg, nunca image/jpg, aunque la extensión de archivo suele ser .jpg. SVG es un caso especial porque es texto, no binario, por lo que a menudo puedes omitir base64 por completo y usar codificación URL en su lugar (más sobre esto a continuación).

Cómo convertir una imagen a Base64#

Tienes tres caminos prácticos según si quieres una cadena única, una conversión en el navegador dentro de tu propia aplicación o una salida en el paso de compilación. Aquí está la ruta más rápida primero, luego el código.

Paso 1: Obtén la cadena con un conversor sin instalación#

Para una conversión rápida y única, no necesitas escribir código. Arrastra el archivo a un codificador y decodificador base64, o usa el conversor de imagen a base64 dedicado cuando quieras que se genere el prefijo completo data:image/.... Pegas o subes, copias el resultado y listo. Esta es la opción correcta cuando solo necesitas la cadena una vez para una regla CSS o una plantilla de correo.

La conversión se ejecuta en tu navegador, por lo que la imagen nunca sale de tu máquina. Esto importa cuando la imagen es un activo privado, un logotipo de cliente o cualquier cosa que no pegarías en una herramienta en línea aleatoria.

Paso 2: Codifica en el navegador con FileReader#

Cuando necesites convertir imágenes dentro de tu propia aplicación web (por ejemplo, un usuario sube un avatar y quieres previsualizarlo antes de enviarlo), la API FileReader te da una URI de datos directamente:

function fileToDataURL(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result); // ya es una URI de datos completa
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

// uso
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async () => {
  const dataURL = await fileToDataURL(input.files[0]);
  document.querySelector('img').src = dataURL; // se renderiza al instante
});

readAsDataURL devuelve la cadena completa data:image/png;base64,..., incluido el prefijo, por lo que puedes asignarla directamente a un src de img o a un background-image. No se necesita detección manual de MIME.

Paso 3: Codifica en el servidor o en tiempo de compilación#

En Node.js lees el archivo como un buffer y llamas a toString('base64'), luego construyes el prefijo tú mismo:

import { readFileSync } from 'node:fs';

const bytes = readFileSync('logo.png');
const base64 = bytes.toString('base64');
const dataURI = `data:image/png;base64,${base64}`;

En Python es casi idéntico:

import base64

with open("logo.png", "rb") as f:
    encoded = base64.b64encode(f.read()).decode("ascii")

data_uri = f"data:image/png;base64,{encoded}"

Herramientas de compilación como webpack y Vite automatizan esto. Vite, por ejemplo, incorpora cualquier activo por debajo de un umbral de tamaño (4KB por defecto) como una URI de datos base64 automáticamente, y deja los archivos más grandes como URLs normales. Ese umbral predeterminado existe precisamente por el cálculo de tamaño de la siguiente sección.

Dónde se usan realmente las imágenes Base64#

La cadena es inútil hasta que la colocas en algún lugar. Los tres lugares comunes:

En HTML, como fuente de img:

<img src="data:image/png;base64,iVBORw0KGgo..." alt="Logotipo en línea" />

En CSS, como fondo:

.icon {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxu...");
}

En JSON o en un payload de API, donde no puedes enviar binario sin procesar, por lo que la imagen viaja como un campo de cadena:

{ "avatar": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ..." }

Ese caso de JSON es uno de los usos legítimos más sólidos. Cuando una API es solo JSON y debes transportar una imagen en línea, base64 es la respuesta estándar.

La penalización del 33% en tamaño que nadie menciona#

Aquí está lo que las páginas de conversión omiten por completo. Base64 codifica 3 bytes de datos binarios en 4 caracteres ASCII. Esa relación es fija: 4/3, lo que supone un aumento de aproximadamente el 33% antes incluso de contar el relleno. Un PNG de 90 KB se convierte en unos 120 KB de texto base64.

Esa sobrecarga no desaparece. Termina en tu archivo HTML o CSS, lo que implica:

  • Cargas útiles HTML o CSS más grandes. Los bytes codificados ahora son parte del documento que el navegador debe descargar y analizar.
  • Sin transmisión ni renderizado progresivo. Una imagen enlazada puede renderizarse a medida que llega. Una incrustada solo aparece después de que toda su cadena se haya descargado como parte del archivo principal.
  • Gzip ayuda, pero no lo suficiente. La compresión recupera parte de la pérdida porque el texto base64 es repetitivo, pero rara vez se vuelve al tamaño binario original, y el costo de CPU de decodificar la cadena es real en dispositivos de gama baja.

Advertencia: incrustar una imagen de héroe o foto grande casi siempre es un error. Una foto de 500 KB se convierte en aproximadamente 665 KB de base64 insertado en tu HTML, bloqueando la finalización del análisis mientras se descarga. Mantenla como un archivo enlazado.

Si tu objetivo es una imagen más pequeña en lugar de una incrustada, la codificación no es la palanca correcta. Reduce primero el archivo con un compresor de imágenes gratuito, luego decide si el activo ahora más pequeño vale la pena incrustarlo.

Cuándo incrustar vs cuándo enlazar#

La decisión se reduce a una pregunta: ¿evitar una solicitud HTTP ahorra más del 33% de sobrecarga que te cuesta? Usa esto como regla general.

Incrustar como base64 cuandoEnlazar como archivo normal cuando
Activos pequeños: iconos pequeños, separadores de 1px, SVG simplesFotos, imágenes principales, cualquier cosa de más de ~5KB
La imagen es crítica y quieres cero solicitudes adicionalesLa imagen puede cargarse de forma diferida o aparece debajo del pliegue
Estás enviando una imagen dentro de JSON o el cuerpo de un correo electrónicoLa imagen se reutiliza en muchas páginas (ventajas de caché)
El activo es de un solo uso y único para una páginaEl activo se beneficia de una CDN o caché del navegador

El punto de la caché es el que los desarrolladores olvidan con más frecuencia. Una imagen enlazada se almacena en caché una vez y se reutiliza en cada página y cada visita. Una imagen incrustada se descarga de nuevo dentro del documento cada vez, en cada página, sin beneficio de caché propio. Para un logotipo que aparece en todo el sitio, enlazar gana de forma decisiva. Para un icono único en una página de aterrizaje, incrustar puede ahorrar una solicitud con un costo insignificante.

En las conexiones modernas HTTP/2 y HTTP/3, la justificación original para incrustar (evitar el costo de muchas solicitudes paralelas) es mucho más débil que en la era HTTP/1.1. La multiplexación de solicitudes hizo que los archivos pequeños fueran baratos de obtener. Esa es otra razón para incrustar con moderación hoy en día.

SVG: el formato donde a menudo te saltas el Base64#

SVG es texto XML, no binario, por lo que Base64 suele ser la opción incorrecta. Puedes insertar un SVG codificado en URL dentro de CSS y evitar por completo la sobrecarga de codificación:

.checkmark {
  background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg"...%3E');
}

Codificar un SVG en URL lo mantiene legible y evita la penalización del 33% de Base64, porque solo escapas los pocos caracteres que rompen dentro de un url() de CSS. Reserva Base64 para formatos binarios (PNG, JPEG, WebP) donde no haya una alternativa legible.

Decodificar una imagen en Base64 de vuelta a un archivo#

Ir en sentido contrario es igual de común. Si tienes una URI de datos y necesitas el archivo original, elimina el prefijo y decodifica el resto. En el navegador:

function dataURLtoBlob(dataURL) {
  const [meta, b64] = dataURL.split(',');
  const mime = meta.match(/data:(.*?);base64/)[1];
  const binary = atob(b64);
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
  return new Blob([bytes], { type: mime });
}

Para una decodificación manual rápida sin código, pega la cadena (con o sin el prefijo) en la misma herramienta de códec base64 y descarga la imagen reconstruida. Si quieres un tutorial más detallado sobre el proceso completo de ida y vuelta de imágenes a través de base64 y URIs de datos, la guía sobre codificar y decodificar imágenes base64 y URIs de datos cubre el ciclo completo con ejemplos.

Errores comunes que rompen las imágenes en línea#

Algunos errores explican casi todas las situaciones de iconos rotos:

  • Tipo MIME incorrecto. Etiquetar un JPEG como image/png confunde a algunos renderizadores. Haz coincidir el prefijo con los bytes reales.
  • Incluir saltos de línea. Algunas herramientas envuelven la salida base64 a 76 caracteres. En un atributo HTML o regla CSS, esos saltos de línea pueden romper la cadena. Usa una sola línea sin interrupciones.
  • Olvidar ;base64. Sin esa bandera, el navegador trata los datos como texto plano o contenido codificado en URL, no como binario codificado.
  • Incrustar imágenes gigantes. Técnicamente válido, prácticamente un error de rendimiento. Vigila el tamaño de tu documento.
  • Pegar imágenes privadas en codificadores en línea no confiables. Prefiere un convertidor que se ejecute del lado del cliente para que el archivo nunca se suba.

Convertir una imagen a Base64, en la práctica#

Para resumir el flujo de trabajo correcto para pasar de imagen a base64: elige el prefijo MIME correcto según el formato, codifica con una herramienta del lado del cliente o FileReader, y ten en cuenta el aumento de tamaño de aproximadamente un 33%. Inserta solo activos pequeños, de un solo uso y críticos para el renderizado, y mantén las fotos e imágenes reutilizadas como archivos enlazados para que el caché del navegador haga su trabajo. Los SVG generalmente necesitan codificación URL, no base64.

Cuando solo necesites la cadena de forma rápida y segura, el codificador y decodificador base64 maneja ambas direcciones en tu navegador, y el convertidor dedicado de imagen a base64 construye la URI de datos completa data:image/... para que puedas pegarla directamente en tu marcado.

Preguntas Frecuentes#

¿Cómo convierto una imagen a base64? Sube o pega el archivo en un codificador del lado del cliente, o usa código: en el navegador llama a FileReader.readAsDataURL(file), y en Node.js lee el archivo como un buffer y llama a buffer.toString('base64'). Luego agrega el prefijo correcto, como data:image/png;base64,, para obtener una URI de datos utilizable.

¿Por qué mi imagen base64 es más grande que el archivo original? Base64 representa 3 bytes de datos binarios como 4 caracteres de texto, lo que infla el tamaño en aproximadamente un 33% antes del relleno. Es una codificación, no un formato de compresión, por lo que la versión codificada siempre es más grande. Si necesitas un recurso más pequeño, comprime la imagen primero y luego decide si incrustarla.

¿Cuál es el prefijo correcto de URI de datos para un JPEG? Es data:image/jpeg;base64,, usando image/jpeg y nunca image/jpg. La extensión del archivo en disco suele ser .jpg, pero el tipo MIME en la URI de datos debe ser jpeg. Un prefijo incorrecto es la razón más común por la que una imagen incrustada se muestra como un icono roto.

¿Debo incrustar imágenes como base64 por rendimiento? Solo para recursos pequeños, de un solo uso y críticos para la renderización, como iconos pequeños. Incrustar evita una solicitud HTTP, pero agrega un 33% de aumento al HTML o CSS, impide que el navegador almacene en caché la imagen por separado y la descarga de nuevo en cada página. Con HTTP/2 y HTTP/3, el beneficio de ahorrar solicitudes es menor que antes, por lo que es mejor enlazar fotos e imágenes reutilizadas.

¿Necesito base64 para imágenes SVG? Generalmente no. SVG es texto, por lo que puedes codificarlo en URL dentro de un url() de CSS y evitar por completo la sobrecarga del 33% de base64, manteniendo el marcado legible. Reserva base64 para formatos binarios como PNG, JPEG y WebP donde no hay una alternativa basada en texto.

¿Es seguro usar un convertidor de imagen a base64 en línea? Depende de si la herramienta procesa el archivo en tu navegador o lo sube a un servidor. Para recursos privados como logotipos de clientes, usa un convertidor que funcione del lado del cliente para que la imagen nunca salga de tu máquina. Las herramientas base64 e imagen a base64 de Molixa codifican localmente en el navegador precisamente por esta razón.

More from Molixa

Try Molixa Tools

50+ free AI tools for content creation, SEO, coding, and more. No signup, no watermark.

Explore all tools