Como converter Base64 para GIF
- Cole o Base64 ou um URI
data:image/gif;base64,...na caixa, ou abra um arquivo.txtque o contenha. - Confira se a linha de status mostra Detectado GIF. A prévia começa a rodar a animação, e o tamanho em pixels aparece acima dela.
- Clique em Baixar arquivo para salvar como
.gif.
Nada é redesenhado nem recompactado. O arquivo salvo tem os mesmos quadros, intervalos, paleta e transparência do GIF que foi codificado.
É mesmo um GIF? E é animado?
Um GIF começa com GIF89a ou GIF87a, que em Base64 é R0lGODlh ou R0lGODdh. Animação, transparência e controle de repetição exigem a versão 89a, mais nova, então uma string que começa com R0lGODdh é, na prática, uma imagem estática.
Se um arquivo 89a se mexe ou não depende do conteúdo: um bloco de imagem ou vários. A prévia mostra isso de cara. Para olhar mais de perto, abra Mostrar dump hex. GIFs animados normalmente trazem o texto NETSCAPE2.0 na coluna ASCII; é o bloco que guarda a contagem de repetições. Com uma tabela de cores pequena, ele fica nas primeiras linhas. Um GIF com tabela completa de 256 cores tem antes 768 bytes de paleta, o que empurra o bloco para além dos 512 bytes que o dump mostra.
Se a página disser “Isto parece ser WebP, não GIF” ou indicar MP4, o “GIF” foi convertido no caminho. Apps de mensagens e serviços de busca de GIFs muitas vezes entregam animações como WebP ou vídeo MP4, porque são bem menores. Use Baixar como para salvar com a extensão real, ou abra em Base64 para vídeo se for um MP4.
Quadros, tempo e repetição no código
Para inspecionar um GIF sem abrir um editor, o Pillow lê tudo o que você precisa:
import base64, io
from PIL import Image
def gif_info(b64: str) -> dict:
data = base64.b64decode(b64.split(",", 1)[-1])
with Image.open(io.BytesIO(data)) as im:
durations = []
for i in range(getattr(im, "n_frames", 1)):
im.seek(i)
durations.append(im.info.get("duration", 0))
return {
"size": im.size,
"frames": len(durations),
"total_ms": sum(durations),
"loop": im.info.get("loop"),
}
Para uma animação de teste com 3 quadros de 100 ms cada, a função devolve {'size': (20, 20), 'frames': 3, 'total_ms': 300, 'loop': 0}. Um loop igual a 0 significa “repetir para sempre”; None significa que o arquivo não tem bloco de repetição e roda uma vez. Mais sobre manipulação de arquivos em Base64 em Python.
De onde vêm os GIFs em Base64
- Spinners de carregamento em CSS e HTML embutidos como
data:image/gif;base64,..., um hábito de antes de animações CSS e SVG se popularizarem. - Templates antigos de e-mail HTML e assinaturas que embutiam pequenos logotipos animados.
- Respostas de API e exportações de chat que trazem figurinhas ou reações como campos Base64.
- Pixels de placeholder: um GIF de 1×1 usado como
srcvazio. A prévia dele parece em branco, então confira as dimensões antes de concluir que a decodificação falhou.
Tamanho do GIF depois de decodificar
Um GIF guarda cada quadro com um esquema de compressão antigo, então animações curtas chegam rápido a megabytes, e o Base64 acrescenta mais um terço. A linha Tamanho mostra o tamanho decodificado: se uma string de GIF “pequeno” tem 5 MB, o GIF tem cerca de 3,75 MB. Decodificar isso aqui não é problema, mas é um péssimo candidato para ser embutido de novo em uma página. Se você for retrabalhar o arquivo, um loop curto em MP4 ou WebM costuma ter uma fração do tamanho. Para codificar um GIF, use GIF para Base64.
Perguntas frequentes
Por que meu GIF decodificado só roda uma vez?
A configuração de repetição faz parte do arquivo. Sem um bloco NETSCAPE2.0, ou com contagem de repetições igual a 1, os navegadores rodam a animação uma vez e param no último quadro. A decodificação mantém o que o arquivo determina; para mudar, use um editor de GIF.
Como contar os quadros de um GIF em Base64?
A prévia roda o GIF, mas não conta os quadros. Em Python, o n_frames do Pillow dá o número, e a soma do duration de cada quadro dá a duração total; o trecho de código desta página faz as duas coisas.
Por que o GIF para no meio ou mostra o último quadro quebrado?
O Base64 foi cortado. Os navegadores rodam os quadros que chegaram e param onde os dados acabam. Um GIF completo termina com o byte de encerramento 3B, então o Base64 dele normalmente termina em ADs=, Ow== ou A7.