O que é Base64?
Base64 é um esquema de codificação de binário para texto que representa dados binários usando apenas 64 caracteres ASCII imprimíveis: as letras maiúsculas A–Z, as letras minúsculas a–z, os dígitos 0–9 e os dois símbolos + e /. Um caractere de preenchimento = é adicionado ao final quando o comprimento da entrada não é múltiplo de três bytes.
O nome "Base64" vem diretamente do tamanho desse conjunto de caracteres. Como cada caractere do conjunto pode ser representado com exatamente 6 bits (2⁶ = 64), o Base64 codifica três bytes (24 bits) de dados binários em quatro caracteres imprimíveis (4 × 6 bits = 24 bits), tornando-o uma codificação sem perdas e reversível.
O Base64 foi originalmente projetado para sistemas de e-mail (MIME) que só podiam transmitir dados textuais de forma confiável. Hoje é usado em todo lugar onde dados binários precisam trafegar por canais somente de texto — de anexos de e-mail e payloads JSON a Data URIs HTML e tokens JWT.
Por que codificar imagens em Base64?
A motivação principal é incorporar dados binários de imagens diretamente em um documento de texto. Um arquivo PNG ou JPEG é binário puro; não pode ser colado em um arquivo HTML ou em um objeto JSON sem ser codificado primeiro. O Base64 resolve isso produzindo uma string de texto puro que pode ser colocada com segurança em qualquer lugar que aceite texto.
Principais razões pelas quais desenvolvedores usam codificação Base64
- Eliminar requisições HTTP — Incorporar uma imagem remove completamente uma requisição de rede. Para ícones pequenos ou elementos decorativos, isso pode reduzir significativamente o tempo no caminho de renderização crítico.
- Distribuição em arquivo único — Arquivos HTML autocontidos (relatórios, templates de e-mail, demos offline) carregam todos os assets sem dependências externas.
- Compatibilidade com HTML de e-mail — Muitos clientes de e-mail bloqueiam carregamentos de imagens externas por padrão por razões de privacidade. Imagens Base64 embutidas contornam essa restrição.
- Payloads de API — Ao enviar uma imagem como parte de um corpo JSON (ex.: um endpoint de upload de avatar), o Base64 permite codificar o arquivo em um campo de string.
- Fundos em CSS — Pequenos Data URIs embutidos em folhas de estilo evitam requisições adicionais para sprites ou ícones decorativos.
- Política de Segurança de Conteúdo (CSP) — Imagens embutidas não estão sujeitas às restrições de host
img-srcda CSP, o que pode simplificar a configuração em ambientes restritos.
Como funciona a codificação Base64
O algoritmo passo a passo
O Base64 processa a entrada em blocos de 3 bytes (24 bits por vez):
- Pegar os próximos três bytes:
B1 B2 B3. - Concatenar seus bits em uma string de 24 bits.
- Dividir os 24 bits em quatro grupos de 6 bits.
- Mapear cada valor de 6 bits (0–63) para seu caractere Base64 usando a tabela de consulta.
- Repetir até que todos os bytes sejam processados.
- Preencher com caracteres
=se o último bloco tiver menos de três bytes.
Exemplo
A string ASCII Man (bytes 0x4D 0x61 0x6E) é codificada assim:
M a n
01001101 01100001 01101110 ← 24 bits
010011 010110 000101 101110
19 22 5 46
T W F u
Resultado: TWFu — três bytes se tornaram quatro caracteres.
O aumento de ~33% no tamanho explicado
Quatro caracteres Base64 carregam cada um 6 bits de informação, totalizando 24 bits. Esses mesmos 24 bits originalmente viviam em três bytes (24 bits). A representação cresce porque cada caractere de saída é armazenado como um byte ASCII completo de 8 bits, não 6 bits:
- Entrada: 3 bytes = 24 bits armazenados em 3 × 8 = 24 bits de armazenamento.
- Saída: 4 caracteres armazenados em 4 × 8 = 32 bits de armazenamento.
- Overhead: 32 / 24 = 1,333… → 33,3% maior.
Com a compressão gzip/Brotli aplicada, o texto codificado em Base64 comprime muito bem (aproximando-se do tamanho original), o que mitiga parcialmente o overhead nas respostas HTTP.
Data URIs explicados
Um Data URI (também chamado de data URL) incorpora o conteúdo de um arquivo diretamente em uma string URI usando o formato definido na RFC 2397:
data:[<mediatype>][;base64],<data>
| Parte | Descrição |
|---|---|
data: |
Identificador de esquema |
<mediatype> |
Tipo MIME (ex. image/png, image/svg+xml) |
;base64 |
Indica que os dados estão codificados em Base64 (omitido para texto simples) |
,<data> |
O payload de dados codificados (ou texto simples) |
Exemplos
Imagem PNG em uma tag <img>:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA..." alt="ícone">
Fundo SVG em CSS:
.logo {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...");
}
SVG sem Base64 (codificado por URL):
SVG já é texto, então pode ser embutido sem Base64 usando codificação percentual:
.icon {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'...%3E%3C/svg%3E");
}
A codificação de URL para SVGs produz uma saída menor que o Base64 para a mesma imagem.
Exemplos de código práticos
Navegador: API FileReader
// Converter arquivo de imagem para Base64 no 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 já inclui o prefixo completo do Data URI (ex. data:image/png;base64,...) e pode ser atribuído diretamente ao src.
Navegador: API Canvas (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 volta para binário
// Decodificar um Data URI Base64 de volta para um 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 e decodificar
import base64
# Codificar imagem em 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], "...") # Prévia
# Decodificar Base64 de volta para imagem
image_data = base64.b64decode(encoded)
with open("output.png", "wb") as f:
f.write(image_data)
CSS: Embutir um ícone pequeno
/* Embutir um ícone pequeno em CSS */
.icon {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...");
width: 24px;
height: 24px;
}
/* Alternativamente, codificar SVGs pequenos por URL para melhor legibilidade */
.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 do mundo real
1. Templates de e-mail
Clientes de e-mail como Outlook, Gmail (em alguns contextos) e webmail corporativo frequentemente bloqueiam carregamentos de imagens externas por padrão. Embutir imagens pequenas como Base64 data URIs no HTML garante que sempre sejam exibidas, independentemente das configurações de privacidade do cliente.
2. Progressive Web Apps (PWA) e apps offline-first
Embutir imagens críticas no shell HTML ou nos assets em cache do service worker garante disponibilidade quando o dispositivo estiver offline, sem adicionar entradas de cache adicionais.
3. Pipelines de processamento de imagens baseados em Canvas
canvas.toDataURL() é o mecanismo de saída padrão para transformações de imagens no navegador — redimensionamento, marca d'água, conversão de formato — antes do upload para um servidor.
4. Funcionalidades de exportação de dados
Gerar relatórios baixáveis (PDF, ZIP, HTML) que precisam carregar suas imagens sem hospedagem externa. Uma fatura HTML completamente autocontida pode ser enviada por e-mail ou arquivada sem preocupação com links de imagens quebrados.
5. Alternativa a sprites CSS para ícones pequenos
Para ícones pontuais pequenos, um único SVG codificado em Base64 como imagem de fundo pode ser mais simples de manter do que uma folha de sprites.
Comparação: Base64 embutido vs arquivo externo
| Fator | Base64 Embutido | Arquivo Externo |
|---|---|---|
| Requisições HTTP | 0 (em linha) | 1 por imagem |
| Overhead de tamanho | ~33% maior | Nenhum |
| Cache do navegador | Não cacheado separadamente | Cacheado por URL |
| Distribuição CDN | Não aplicável | Suporte CDN completo |
| Invalidação de cache | Atualizar documento pai | Mudar nome/hash do arquivo |
| Ideal para | Ícones pequenos < 5 KB | Fotos, imagens grandes |
| Compatibilidade com e-mail | Excelente | Frequentemente bloqueado |
| Suporte offline | Incorporado | Requer service worker |
Trade-offs de performance e considerações
Quando o Base64 melhora a performance
- Imagens muito pequenas (< 2–5 KB): O custo da requisição HTTP (resolução DNS + handshake TCP + negociação TLS + requisição/resposta) para um arquivo pequeno frequentemente excede a penalidade de 33% de tamanho.
- Ambientes HTTP/1.1: Navegadores limitam conexões simultâneas por host (tipicamente 6). Reduzir o número de requisições é mais impactante aqui do que sob HTTP/2.
- Imagens críticas above-the-fold: Embutir um ícone hero ou logotipo significa que ele é renderizado com o primeiro byte HTML — sem viagens de ida e volta adicionais.
Quando o Base64 prejudica a performance
- Imagens grandes (> 5–10 KB): O overhead de tamanho torna-se significativo. Um PNG de 100 KB torna-se ~133 KB em Base64.
- Imagens reutilizadas: Um arquivo de imagem externo é baixado uma vez e reutilizado do cache em múltiplas páginas. Uma string Base64 embutida em cada página é rebaixada a cada carregamento.
- Multiplexação HTTP/2: Sob HTTP/2, muitas pequenas requisições são multiplexadas em uma única conexão com overhead mínimo. O argumento de "eliminar requisições" enfraquece substancialmente.
- Tempo de análise do documento: Uma grande string Base64 contribui para o tempo de análise do HTML.
- Cache do navegador: Data URIs embutidos em HTML são cacheados apenas como parte do documento e não podem ser compartilhados entre páginas.
Nota sobre compressão
O texto codificado em Base64 comprime muito bem com gzip/Brotli devido à sua alta redundância (conjunto de caracteres limitado, padrões repetidos). Quando a compressão HTTP está habilitada, a penalidade efetiva de tamanho de transferência cai para cerca de 2–8% para imagens típicas.
Melhores práticas
Definir um limiar de tamanho. Embutir imagens abaixo de 2–5 KB; usar URLs externas para tudo maior. Muitos bundlers (webpack, Vite) aplicam essa regra automaticamente via
url-loader/asset/inline.Preferir SVG a raster para ícones. SVGs já são texto e comprimem melhor que Base64 raster. Usar codificação URL (
encodeURIComponent) em vez de Base64 para SVGs para mantê-los legíveis.Habilitar compressão HTTP. Garantir que gzip ou Brotli esteja habilitado no servidor para que o overhead de 33% seja amplamente mitigado em trânsito.
Usar WebP ou AVIF. Formatos modernos produzem arquivos muito menores antes da codificação, tornando a saída Base64 proporcionalmente menor também.
Auditar com DevTools. Verificar a aba Network. Se imagens embutidas estão tornando o documento HTML significativamente maior, considerar movê-las para URLs externas com CDN e headers de cache de longa duração.
Para e-mails, testar em vários clientes. Nem todos os clientes de e-mail renderizam data URIs de forma idêntica. Testar no Outlook, Gmail (web e app), Apple Mail e clientes móveis antes de confiar em imagens embutidas para conteúdo crítico.
Remover metadados antes de codificar. Usar uma ferramenta que remova dados EXIF antes de embutir — EXIF pode adicionar kilobytes de dados desnecessários (e potencialmente expor coordenadas GPS sensíveis).
Usar ferramentas em tempo de build. Em vez de codificar imagens manualmente, usar
asset/inlinedo webpack, o sufixo de importação?inlinedo Vite, ou PostCSSpostcss-inline-base64para automatizar o processo de forma confiável.
SVG vs imagens raster: uma nota sobre codificação
Imagens SVG são texto XML, o que significa que podem ser embutidas em CSS sem Base64 simplesmente codificando o marcação em URL. Essa abordagem é preferida porque:
- O resultado é menor que o Base64 para conteúdo SVG.
- O SVG permanece legível dentro da folha de estilos.
- Sem overhead de decodificação.
/* 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 em Base64 — aceitável mas menos legível */
.checkmark-b64 {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...");
}
Perguntas frequentes (FAQ)
P1: Qual é o tamanho máximo de um Data URI?
Não existe um limite padrão rígido, mas os navegadores impõem limites práticos. Chrome e Firefox lidam com data URIs de até ~2 MB sem problemas. O Internet Explorer historicamente limitava data URIs a 32 KB. Para uso em produção, manter imagens embutidas abaixo de 5 KB para evitar impactar o tempo de análise do documento.
P2: Posso usar imagens Base64 na propriedade CSS content:?
Sim. Pseudo-elementos aceitam data URIs em content: url(...):
.badge::before {
content: url("data:image/png;base64,...");
}
Note que content: url() renderiza a imagem em seu tamanho intrínseco e não pode ser redimensionado com width/height — usar background-image para controle de tamanho.
P3: A codificação Base64 afeta a qualidade da imagem?
Não. Base64 é uma codificação sem perdas. Ele codifica e decodifica os bytes originais exatos sem nenhuma modificação. A qualidade da imagem é determinada exclusivamente pelo arquivo de imagem original e seu formato (JPEG com perdas vs PNG/WebP sem perdas).
P4: Como decodifico uma string Base64 de volta para um arquivo?
No navegador:
const byteString = atob(base64String); // decodificar
Em Python:
import base64
data = base64.b64decode(b64_string)
Em Node.js:
const buf = Buffer.from(b64String, 'base64');
P5: Imagens Base64 são indexadas pelos mecanismos de busca?
Mecanismos de busca podem indexar imagens entregues via data URIs, mas podem não rastreá-las tão eficientemente quanto imagens hospedadas externamente. Para imagens críticas para SEO, hospedá-las externamente com nomes de arquivo descritivos, texto alt adequado e marcação de dados estruturados.
P6: Por que minha string Base64 termina com ==?
Caracteres de preenchimento (=) são adicionados quando o número de bytes de entrada não é divisível por 3. Um = significa que o último bloco tinha 2 bytes (16 bits → 18 bits codificados → 1 caractere de preenchimento). Dois == significam que o último bloco tinha apenas 1 byte (8 bits → 12 bits codificados → 2 caracteres de preenchimento).
P7: Base64 é uma forma de criptografia?
Não. Base64 é puramente um esquema de codificação, não criptografia. Ele não fornece confidencialidade — qualquer um pode decodificá-lo instantaneamente. Não use Base64 para "esconder" dados sensíveis. Para segurança, use criptografia real (AES, RSA, etc.).
P8: Qual é a diferença entre Base64 e Base64url?
Base64url é uma variante do Base64 projetada para ser segura em URLs. Usa - em vez de + e _ em vez de /, e omite o preenchimento =. É comumente usado em JWTs e outras aplicações web onde os caracteres +, / e = causam problemas em parâmetros de URL.