¿Qué es Base64?
Base64 es un esquema de codificación binario a texto que representa datos binarios usando solo 64 caracteres ASCII imprimibles: las letras mayúsculas A–Z, las letras minúsculas a–z, los dígitos 0–9 y los dos símbolos + y /. Se añade un carácter de relleno = al final cuando la longitud de entrada no es múltiplo de tres bytes.
El nombre "Base64" proviene directamente del tamaño de este conjunto de caracteres. Como cada carácter del conjunto puede representarse con exactamente 6 bits (2⁶ = 64), Base64 codifica tres bytes (24 bits) de datos binarios en cuatro caracteres imprimibles (4 × 6 bits = 24 bits), convirtiéndolo en una codificación sin pérdidas y reversible.
Base64 fue diseñado originalmente para los sistemas de correo electrónico (MIME) que solo podían transmitir datos de texto de forma confiable. Hoy se usa en todas partes donde los datos binarios deben viajar por canales solo de texto: adjuntos de correo, cargas útiles JSON, Data URIs HTML y tokens JWT.
¿Por qué codificar imágenes a Base64?
La motivación principal es incrustar datos de imagen binarios directamente en un documento de texto. Un archivo PNG o JPEG es binario puro; no se puede pegar en un archivo HTML o en un objeto JSON sin codificarlo antes. Base64 resuelve esto produciendo una cadena de texto plano que es segura de colocar en cualquier lugar donde se acepte texto.
Razones principales por las que los desarrolladores recurren a la codificación Base64
- Eliminar solicitudes HTTP — Incrustar una imagen elimina una solicitud de red por completo. Para iconos pequeños o elementos decorativos esto puede reducir significativamente el tiempo en la ruta de renderizado crítico.
- Distribución en un solo archivo — Los archivos HTML autocontenidos (informes, plantillas de correo, demos offline) llevan todos los activos sin dependencias externas.
- Compatibilidad con HTML de correo — Muchos clientes de correo bloquean las solicitudes de imágenes externas por razones de privacidad. Las imágenes Base64 en línea eluden esta restricción.
- Cargas útiles de API — Al enviar una imagen como parte de un cuerpo JSON (p. ej., un endpoint de carga de avatar), Base64 permite codificar el archivo en un campo de cadena.
- Fondos en CSS — Tiny data URIs incrustados en hojas de estilo evitan solicitudes adicionales para sprites o iconos decorativos.
- Política de seguridad de contenido (CSP) — Las imágenes incrustadas no están sujetas a restricciones de host
img-srcde CSP, lo que puede simplificar la configuración de políticas en entornos restringidos.
Cómo funciona la codificación Base64
El algoritmo paso a paso
Base64 procesa la entrada en bloques de 3 bytes (24 bits a la vez):
- Tomar los siguientes tres bytes:
B1 B2 B3. - Concatenar sus bits en una cadena de 24 bits.
- Dividir los 24 bits en cuatro grupos de 6 bits.
- Mapear cada valor de 6 bits (0–63) a su carácter Base64 usando la tabla de búsqueda.
- Repetir hasta que todos los bytes estén procesados.
- Rellenar con caracteres
=si el último bloque tiene menos de tres bytes.
Ejemplo
La cadena ASCII Man (bytes 0x4D 0x61 0x6E) se codifica así:
M a n
01001101 01100001 01101110 ← 24 bits
010011 010110 000101 101110
19 22 5 46
T W F u
Resultado: TWFu — tres bytes se convirtieron en cuatro caracteres.
El aumento de ~33% en el tamaño explicado
Cuatro caracteres Base64 llevan cada uno 6 bits de información, totalizando 24 bits. Esos mismos 24 bits originalmente vivían en tres bytes (24 bits). La representación crece porque cada carácter de salida se almacena como un byte ASCII completo de 8 bits, no 6 bits:
- Entrada: 3 bytes = 24 bits almacenados en 3 × 8 = 24 bits de almacenamiento.
- Salida: 4 caracteres almacenados en 4 × 8 = 32 bits de almacenamiento.
- Sobrecarga: 32 / 24 = 1.333… → 33.3% más grande.
Con compresión gzip/Brotli aplicada, el texto codificado en Base64 se comprime muy bien (acercándose al tamaño original), lo que mitiga parcialmente la sobrecarga en respuestas HTTP.
Data URIs explicados
Un Data URI (también llamado data URL) incrusta el contenido del archivo directamente en una cadena URI usando el formato definido en RFC 2397:
data:[<mediatype>][;base64],<data>
| Parte | Descripción |
|---|---|
data: |
Identificador de esquema |
<mediatype> |
Tipo MIME (ej. image/png, image/svg+xml) |
;base64 |
Indica que los datos están codificados en Base64 (se omite para texto plano) |
,<data> |
La carga útil de datos codificados (o texto plano) |
Ejemplos
Imagen PNG en una etiqueta <img>:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA..." alt="icono">
Fondo SVG en CSS:
.logo {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...");
}
SVG sin Base64 (codificado por URL):
El SVG ya es texto, por lo que puede incrustarse sin Base64 usando codificación de porcentaje:
.icon {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'...%3E%3C/svg%3E");
}
La codificación de URL para SVGs produce una salida más pequeña que Base64 para la misma imagen.
Ejemplos de código prácticos
Navegador: FileReader API
// Convertir archivo de imagen a Base64 en el navegador
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
});
}
// Uso
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async (e) => {
const base64 = await fileToBase64(e.target.files[0]);
document.querySelector('img').src = base64;
});
reader.result ya incluye el prefijo completo del Data URI (ej. data:image/png;base64,...), por lo que puede asignarse directamente a src.
Navegador: Canvas API (redimensionar + codificar)
function resizeAndEncode(file, maxWidth = 200) {
return new Promise((resolve) => {
const img = new Image();
const url = URL.createObjectURL(file);
img.onload = () => {
const scale = Math.min(1, maxWidth / img.width);
const canvas = document.createElement('canvas');
canvas.width = img.width * scale;
canvas.height = img.height * scale;
canvas.getContext('2d').drawImage(img, 0, 0, canvas.width, canvas.height);
URL.revokeObjectURL(url);
resolve(canvas.toDataURL('image/webp', 0.85));
};
img.src = url;
});
}
JavaScript: Decodificar Base64 de vuelta a binario
// Decodificar un Data URI Base64 de vuelta a un Blob
function dataURItoBlob(dataURI) {
const [header, data] = dataURI.split(',');
const mime = header.match(/:(.*?);/)[1];
const binary = atob(data);
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 });
}
Python: Codificar y decodificar
import base64
# Codificar imagen a Base64
with open("image.png", "rb") as f:
encoded = base64.b64encode(f.read()).decode("utf-8")
data_uri = f"data:image/png;base64,{encoded}"
print(data_uri[:80], "...") # Vista previa
# Decodificar Base64 de vuelta a imagen
image_data = base64.b64decode(encoded)
with open("output.png", "wb") as f:
f.write(image_data)
CSS: Incrustar un icono pequeño
/* Incrustar un icono pequeño en CSS */
.icon {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...");
width: 24px;
height: 24px;
}
/* Alternativamente, codificar por URL SVGs pequeños para mejor legibilidad */
.icon-alt {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E...%3C/svg%3E");
}
Casos de uso del mundo real
1. Plantillas de correo electrónico
Los clientes de correo como Outlook, Gmail (en algunos contextos) y el correo web corporativo a menudo bloquean las cargas de imágenes externas por defecto. Incrustar imágenes pequeñas como Base64 data URIs en el HTML garantiza que siempre se muestren, independientemente de la configuración de privacidad del cliente.
2. Aplicaciones web progresivas (PWA) y apps offline-first
Inlinear imágenes críticas en el shell HTML o en los activos en caché del service worker garantiza disponibilidad cuando el dispositivo está offline, sin añadir entradas de caché adicionales.
3. Pipelines de procesamiento de imágenes basados en Canvas
canvas.toDataURL() es el mecanismo de salida estándar para transformaciones de imágenes en el navegador —redimensionar, añadir marcas de agua, convertir formatos— antes de subir a un servidor.
4. Funciones de exportación de datos
Generar informes descargables (PDF, ZIP, HTML) que deben llevar sus imágenes sin alojamiento externo. Una factura HTML completamente autocontenida puede enviarse por correo o archivarse sin preocuparse por enlaces de imágenes rotos.
5. Alternativa a sprites CSS para iconos pequeños
Para iconos únicos pequeños, un solo SVG codificado en Base64 como fondo puede ser más simple de mantener que una hoja de sprites.
Comparación: Base64 incrustado vs archivo externo
| Factor | Base64 Incrustado | Archivo Externo |
|---|---|---|
| Solicitudes HTTP | 0 (en línea) | 1 por imagen |
| Sobrecarga de tamaño | ~33% más grande | Ninguna |
| Caché del navegador | No se cachea por separado | Cacheado por URL |
| Distribución CDN | No aplica | Soporte CDN completo |
| Invalidación de caché | Actualizar documento padre | Cambiar nombre/hash de archivo |
| Mejor para | Iconos pequeños < 5 KB | Fotos, imágenes grandes |
| Compatibilidad con correo | Excelente | A menudo bloqueado |
| Soporte offline | Integrado | Requiere service worker |
Compensaciones de rendimiento y consideraciones
Cuándo Base64 mejora el rendimiento
- Imágenes muy pequeñas (< 2–5 KB): El costo de la solicitud HTTP (búsqueda DNS + negociación TCP + TLS + solicitud/respuesta) para un archivo pequeño a menudo supera la penalización del 33% de tamaño.
- Entornos HTTP/1.1: Los navegadores limitan las conexiones concurrentes por host (típicamente 6). Reducir el número de solicitudes es más impactante aquí que bajo HTTP/2.
- Imágenes críticas above-the-fold: Inlinear un icono hero o logotipo significa que se renderiza con el primer byte HTML — sin viajes de ida y vuelta adicionales.
Cuándo Base64 perjudica el rendimiento
- Imágenes grandes (> 5–10 KB): La sobrecarga de tamaño se vuelve significativa. Un PNG de 100 KB se convierte en ~133 KB en Base64.
- Imágenes repetidas: Un archivo de imagen externo se descarga una vez y se reutiliza desde caché en múltiples páginas. Una cadena Base64 incrustada en cada página se vuelve a descargar en cada carga.
- Multiplexación HTTP/2: Bajo HTTP/2, muchas solicitudes pequeñas se multiplexan sobre una sola conexión con mínima sobrecarga. El argumento de "eliminar solicitudes" se debilita sustancialmente.
- Tiempo de análisis del documento: Una cadena Base64 grande contribuye al tiempo de análisis del HTML.
- Caché del navegador: Los Data URIs incrustados en HTML solo se cachean como parte del documento y no pueden compartirse entre páginas.
Nota sobre compresión
El texto codificado en Base64 se comprime muy bien con gzip/Brotli debido a su alta redundancia (conjunto de caracteres limitado, patrones repetidos). Cuando la compresión HTTP está habilitada, la penalización de tamaño de transferencia efectiva cae a alrededor del 2–8% para imágenes típicas.
Mejores prácticas
Establece un umbral de tamaño. Incrusta imágenes de menos de 2–5 KB; usa URLs externas para todo lo demás. Muchos empaquetadores (webpack, Vite) aplican esta regla automáticamente con
url-loader/asset/inline.Prefiere SVG sobre raster para iconos. Los SVGs ya son texto y se comprimen mejor que el raster Base64. Usa URL-encoding (
encodeURIComponent) en lugar de Base64 para SVGs para mantenerlos legibles.Habilita la compresión HTTP. Asegúrate de que gzip o Brotli estén habilitados en tu servidor para que la sobrecarga del 33% se mitigue principalmente en tránsito.
Usa WebP o AVIF. Los formatos modernos producen archivos mucho más pequeños antes de la codificación, haciendo la salida Base64 proporcionalmente más pequeña también.
Audita con DevTools. Comprueba la pestaña Network. Si las imágenes incrustadas hacen tu documento HTML significativamente más grande, considera moverlas a URLs externas con CDN y cabeceras de caché de larga duración.
Para correo, prueba en varios clientes. No todos los clientes de correo renderizan los data URIs de forma idéntica. Prueba en Outlook, Gmail (web y app), Apple Mail y clientes móviles antes de confiar en imágenes en línea para contenido crítico.
Elimina metadatos antes de codificar. Usa una herramienta que elimine datos EXIF antes de incrustar — EXIF puede añadir kilobytes de datos innecesarios (y potencialmente exponer coordenadas GPS sensibles).
Usa herramientas en tiempo de compilación. En lugar de codificar imágenes manualmente, usa
asset/inlinede webpack, el sufijo de importación?inlinede Vite, o PostCSSpostcss-inline-base64para automatizar el proceso de forma fiable.
SVG vs imágenes raster: una nota sobre la codificación
Las imágenes SVG son texto XML, lo que significa que pueden incrustarse en CSS sin Base64 simplemente codificando el marcado en URL. Este enfoque es preferido porque:
- El resultado es más pequeño que Base64 para contenido SVG.
- El SVG permanece legible dentro de la hoja de estilos.
- Sin sobrecarga de decodificación.
/* SVG codificado por URL — preferido para SVGs */
.checkmark {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
}
/* SVG codificado en Base64 — aceptable pero menos legible */
.checkmark-b64 {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...");
}
Preguntas frecuentes (FAQ)
P1: ¿Cuál es el tamaño máximo de un Data URI?
No existe un límite estándar estricto, pero los navegadores imponen límites prácticos. Chrome y Firefox manejan data URIs de hasta ~2 MB sin problemas. Internet Explorer históricamente limitaba los data URIs a 32 KB. Para uso en producción, mantén las imágenes incrustadas por debajo de 5 KB para evitar impactar en el tiempo de análisis del documento.
P2: ¿Puedo usar imágenes Base64 en la propiedad CSS content:?
Sí. Los pseudo-elementos aceptan data URIs en content: url(...):
.badge::before {
content: url("data:image/png;base64,...");
}
Ten en cuenta que content: url() renderiza la imagen a su tamaño intrínseco y no se puede redimensionar con width/height — usa background-image en cambio para control de tamaño.
P3: ¿La codificación Base64 afecta la calidad de la imagen?
No. Base64 es una codificación sin pérdidas. Codifica y decodifica los bytes originales exactos sin ninguna modificación. La calidad de la imagen está determinada únicamente por el archivo de imagen original y su formato (JPEG con pérdidas vs PNG/WebP sin pérdidas).
P4: ¿Cómo decodifico una cadena Base64 de vuelta a un archivo?
En el navegador:
const byteString = atob(base64String); // decodificar
En Python:
import base64
data = base64.b64decode(b64_string)
En Node.js:
const buf = Buffer.from(b64String, 'base64');
P5: ¿Los buscadores indexan las imágenes Base64?
Los motores de búsqueda pueden indexar imágenes entregadas mediante data URIs, pero pueden no rastrearlas tan eficientemente como las imágenes alojadas externamente. Para imágenes críticas para SEO, alójalas externamente con nombres de archivo descriptivos, texto alt adecuado y marcado de datos estructurados.
P6: ¿Por qué mi cadena Base64 termina con ==?
Los caracteres de relleno (=) se añaden cuando el número de bytes de entrada no es divisible entre 3. Un = significa que el último bloque tenía 2 bytes (16 bits → 18 bits codificados → 1 carácter de relleno). Dos == significan que el último bloque tenía 1 byte (8 bits → 12 bits codificados → 2 caracteres de relleno).
P7: ¿Es Base64 una forma de cifrado?
No. Base64 es puramente un esquema de codificación, no cifrado. No proporciona confidencialidad — cualquiera puede decodificarlo instantáneamente. No uses Base64 para "ocultar" datos sensibles. Para seguridad, usa cifrado real (AES, RSA, etc.).
P8: ¿Qué diferencia hay entre Base64 y Base64url?
Base64url es una variante de Base64 diseñada para ser segura en URLs. Usa - en lugar de + y _ en lugar de /, y omite el relleno =. Se usa comúnmente en JWTs y otras aplicaciones web donde los caracteres +, / y = causan problemas en parámetros de URL.