Análises Profundas

O que é HEIC? Um mergulho técnico profundo em assinaturas de arquivo, detecção e conversão

koboshiCo-founder
·6 min de leitura
O que é HEIC? Um mergulho técnico profundo em assinaturas de arquivo, detecção e conversão
Resumo

HEIC não é apenas um JPEG menor. É um formato contêiner baseado no ISO Base Media File Format com imagens codificadas em HEVC no interior. Veja como funciona, como detectá-lo lendo bytes brutos, e como convertê-lo quando a compatibilidade falha.

Abra um arquivo HEIC em um editor hexadecimal. Os primeiros doze bytes:

00 00 00 18 66 74 79 70 68 65 69 63

Isso é ISOBMFF — o mesmo padrão de contêiner que o MP4 usa. 0x18 (24 bytes) é o tamanho da caixa, ftyp é a caixa de tipo de arquivo, heic é a marca principal. Um arquivo HEIC não é uma codificação de imagem. É um contêiner com um marcador de marca, abrigando imagens codificadas em HEVC.

O que HEIC realmente é

HEIC = High Efficiency Image Container. A implementação com marca da Apple do HEIF, padronizado pelo MPEG como ISO/IEC 23008-12 em 2015. JPEG é tanto um algoritmo de compressão quanto um formato de arquivo. HEIC é apenas um contêiner. A compressão interna é HEVC (H.265), o mesmo codec usado para vídeo 4K.

Um único arquivo HEIC pode armazenar:

  • Uma imagem principal
  • Múltiplas imagens alternativas (fotos em sequência)
  • Sequências de imagens (Live Photos: imagem estática + vídeo de 3 segundos)
  • Canais alfa e mapas de profundidade
  • Profundidade de cor de 16 bits por canal (JPEG é limitado a 8 bits)

O contêiner usa uma estrutura de caixas — exatamente como o MP4:

BoxPropósito
ftypTipo de arquivo e marcas compatíveis
metaMetadados e propriedades do item
mdatDados de imagem codificados brutos (bitstream HEVC)
ilocLocalizações de itens dentro de mdat

Essa extensibilidade permite que o HEIC faça coisas que o JPEG nunca pôde fazer. Analisá-lo requer entender a hierarquia de caixas, não apenas ler um bitstream bruto.

Por que a Apple mudou

A Apple não inventou o HEIC. O MPEG publicou o HEIF em 2015. A Apple o adotou como formato de câmera padrão do iPhone no iOS 11 (2017).

A mudança foi aritmética, não marketing. Uma foto típica de iPhone de 12 MP em JPEG é ~3,5 MB. Em HEIC, ~1,8 MB. Com 50 GB do nível gratuito de armazenamento do iCloud, essa diferença significa aproximadamente 14.000 fotos adicionais. A Apple vende níveis de armazenamento. A conta se faz sozinha.

Houve também o alinhamento do ecossistema. A Apple já havia adotado o HEVC para vídeo (H.265 no iOS 11). Reutilizar o mesmo codec para imagens estáticas significava blocos de decodificação de hardware compartilhados nos chips da série A, menor consumo de energia e um único caminho de licenciamento.

Os prós e contras

O HEIC é superior ao JPEG em quase todas as métricas, exceto a compatibilidade.

AspectoHEICJPEG
Eficiência de compressão~40–50% menor na mesma qualidadeLinha de base
Profundidade de corAté 16 bits8 bits
TransparênciaSimNão
Múltiplas imagens por arquivoSimNão
Reedição sem perdaSimNão
Suporte nativo do WindowsRequer extensão HEIFUniversal
Suporte de navegadores webApenas SafariUniversal
Suporte do AndroidNativo em 9+Universal
Licenciamento de patentesPool de patentes HEVCJPEG é isento de royalties

O HEVC é coberto por múltiplos pools de patentes (MPEG LA, Access Advance). A Apple cobre as taxas para os usuários do iOS. Terceiros não têm esse privilégio. Essa incerteza é grande parte da razão pela qual a adoção fora do ecossistema da Apple estagnou.

Detectando HEIC lendo a assinatura do arquivo

Não confie na extensão .heic. Leia os primeiros 32 bytes e analise a caixa ftyp.

Layout exato de bytes do cabeçalho de um arquivo HEIC válido:

Bytes 0–3:   Tamanho da caixa (uint32 big-endian)
Bytes 4–7:   Tipo da caixa: "ftyp" (0x66 0x74 0x79 0x70)
Bytes 8–11:  Marca principal: "heic" ou "heif" ou "mif1"
Bytes 12–15: Versão menor (geralmente 0x00000000)
Bytes 16+:   Lista de marcas compatíveis (ex. "mif1", "heic", "MiHE")

TypeScript do lado do navegador:

async function isHeic(file: File): Promise<boolean> {
  const buffer = await file.slice(0, 32).arrayBuffer()
  const bytes = new Uint8Array(buffer)

  if (String.fromCharCode(...bytes.slice(4, 8)) !== "ftyp") return false

  const brand = String.fromCharCode(...bytes.slice(8, 12))
  return ["heic", "heif", "mif1", "msf1"].includes(brand)
}

Nosso conversor executa essa verificação antes de tentar a decodificação. Marca errada = rejeição imediata, sem ciclos de CPU desperdiçados.

Python

def is_heic(path: str) -> bool:
    with open(path, "rb") as f:
        header = f.read(32)

    if len(header) < 12:
        return False

    if header[4:8].decode("ascii", errors="ignore") != "ftyp":
        return False

    return header[8:12].decode("ascii", errors="ignore") in {"heic", "heif", "mif1", "msf1"}

Verificação de nível superior com filetype:

import filetype

kind = filetype.guess("photo.heic")
if kind and kind.extension in ("heic", "heif"):
    print(kind.mime)  # image/heic

Ou com pillow-heif:

from pillow_heif import is_heif

if is_heif("photo.heic"):
    # contêiner válido
    pass

Go

func isHeic(path string) bool {
	f, err := os.Open(path)
	if err != nil {
		return false
	}
	defer f.Close()

	buf := make([]byte, 32)
	if _, err := f.Read(buf); err != nil {
		return false
	}

	if string(buf[4:8]) != "ftyp" {
		return false
	}

	brand := string(buf[8:12])
	return brand == "heic" || brand == "heif" || brand == "mif1" || brand == "msf1"
}

PHP

function isHeic(string $path): bool {
    $header = file_get_contents($path, false, null, 0, 32);
    if (strlen($header) < 12) return false;
    if (substr($header, 4, 4) !== 'ftyp') return false;

    return in_array(substr($header, 8, 4), ['heic', 'heif', 'mif1', 'msf1'], true);
}

Com fileinfo:

$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file('photo.heic');
// image/heic ou image/heif

ImageMagick CLI

ImageMagick 7+ suporta HEIC se compilado com libheif:

magick identify -verbose photo.heic | grep "Format:"
# Format: HEIC (High Efficiency Image Container)

Sem libheif: no decode delegate for this image format. Na maioria das distribuições Linux, libheif-examples fornece heif-convert como alternativa.

O caminho da conversão

Saber que um arquivo é HEIC não significa que você pode abri-lo. O Windows exige as HEIF Image Extensions. A maioria dos navegadores ainda se recusa a renderizar HEIC em tags <img>. O Android 9+ lida com isso nativamente; dispositivos mais antigos não.

A solução: converter. Nosso conversor de HEIC para JPG lida com todo o pipeline no seu navegador:

  1. Soltar arquivos — fotos individuais ou pastas inteiras, o processamento em lote é automático.
  2. Validação de assinatura — a verificação exata de bytes acima é executada em cada arquivo. Arquivos que não são HEIC são imediatamente rejeitados com uma mensagem clara.
  3. Decodificação do lado do cliente — uma compilação WebAssembly do libheif é executada localmente. Sem uploads. Sem servidores.
  4. Saída que preserva a qualidade — JPG com 90% de qualidade preserva a resolução e a precisão de cor originais.
  5. Download em lote — arquivos individuais ou um único arquivo ZIP.

Para saída sem perda com transparência: HEIC para PNG. Para tamanhos otimizados para web: HEIC para WebP.

Seus arquivos nunca deixam seu dispositivo. É disso que se trata.

Mais posts do blog