Menor imagem de URI de dados possível para uma imagem transparente


125

Estou usando uma imagem transparente de 1x1 com uma imagem de fundo, para poder usar sprites e ainda fornecer texto alternativo para alguns ícones.

Desejo usar um URI de dados para a imagem para reduzir o número de solicitações HTTP, mas qual seria a menor string possível para produzir uma imagem transparente ?

Sei que poderia usar dados URI: s para as imagens reais em vez de sprites, mas é mais fácil manter quando tudo é mantido no CSS em vez de espalhado.


1
Não seria melhor usar uma imagem 1x1 real, com a configuração de cache? Você não possui mais solicitações de HTTP e, no total de dados indiretos, o URL da imagem pode ser menor que os 78 bytes do URI de dados.
Redzarf #

1
@ Redzarf: na verdade, não, provavelmente não seria melhor. recursos pequenos e raramente alterados afetam o tempo de carregamento da página, não por causa do tamanho do arquivo, mas por causa da ida e volta de uma solicitação HTTP. Outra sutileza é que a maioria dos navegadores é muito mais agressiva quanto ao cache de CSS do que outros recursos, portanto, é menos provável que o navegador experimente atualizar css (e conteúdo assim incorporado), economizando mais viagens de ida e volta com http.
SingleNegationElimination

Respostas:


167

Depois de brincar com diferentes GIFs transparentes, alguns são instáveis ​​e causam falhas de CSS. Por exemplo, se você possui um <img>e usa o menor GIF transparente possível, ele funciona bem; no entanto, se você deseja que seu GIF transparente tenha um background-image, isso é impossível. Por alguma razão, alguns GIFs, como os seguintes, impedem os fundos CSS (em alguns navegadores).

Mais curto (mas instável - 74 bytes)

data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

Eu recomendaria usar a versão um pouco mais longa e mais estável da seguinte maneira:

⇊ Estável ⇊ (mas um pouco mais longo - 78 bytes)

data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7

Como outra dica, não omita image/gifcomo sugere um comentário. Isso quebrará em vários navegadores.


1
+1 obrigado! Notei que isso é útil. Usei seus dados para criar este plug-in para poder usar imagens de tipo responsivo nativamente com capa de fundo ou conter-
Jason Sebring

1
Por que o mais curto é "instável"? Vejo que ocasionalmente causa uma imagem negra, só estou curioso se alguém sabe o porquê.
jvenema

Depois de muita dor, descobri que a versão "mais curta" estava travando o navegador em algumas (não todas) páginas do meu site em navegadores Android mais antigos (HTC One S, OS 4.1).
WebSeed 01/02

Ótima resposta, mas não a menor possível até agora.
Josh Habdas 28/01/19

22
data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E

O comprimento final depende do que foi compactado.


3
Existem argumentos contra o uso de um SVG? Algum caso em que não é uma boa ideia?
tremby

Um SVG é bom para muitos casos, mas quando combinado com width: auto;, um SVG assume a largura de seu pai. Uma imagem estática, como GIF ou PNG, quando recebe uma altura e largura fixas automaticamente, manterá sua proporção.
snazzybouche


14

PNG menor - 114 bytes:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=

Vale ressaltar que isso é facilmente gerável usando o GIMP. O arquivo resultante terá um tamanho de 68 bytes (o menor possível até agora).
Ismael Miguel

@AminahNuraini este é um PNG.
joshcarr

2
@AminahNuraini: E essa resposta diz "SVG" para você?
Lightness Races em órbita

10

Esse cara detalha o problema por meio da especificação do GIF. Sua solução para o transparent.gifseria 37 bytes:

data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

Ele fica ainda menor removendo primeiro a transparência e depois a tabela de cores ...


Especificação GIF89a

  • Cabeçalho (6 bytes)

    Consiste nos bytes "GIF" e no número da versão, normalmente 89a.

  • Descritor de tela lógica (7 bytes)

    Sem entrar em muitos detalhes, esta seção do arquivo indica o seguinte:

    • O arquivo tem tamanho de 1x1 pixels.
    • Existe uma tabela de cores global.
    • Existem 2 cores na tabela de cores global; a segunda deve ser usada como cor de fundo.
  • Tabela de cores global (6 bytes)

    Consiste em 3 bytes por cor, um byte para vermelho, verde e azul, respectivamente. Em nosso arquivo, a primeira cor é branca e a segunda cor é preta.

  • Extensão de controle gráfico (8 bytes)

    Usado para indicar que a segunda cor na tabela de cores deve ser tratada como transparente (também pode ser usada para parâmetros de animação, mas não está neste arquivo).

  • Descritor de Imagem (10 bytes)

    Na verdade, um arquivo GIF pode conter várias "imagens", o que impede que você precise especificar dados da imagem para partes da imagem com a mesma cor da cor de fundo. Cada bloco de imagem tem uma posição e tamanho dentro do tamanho geral da imagem. No arquivo acima, a posição é 0,0 e o tamanho é 1x1.

  • Dados da imagem (5 bytes)

    Um bloco de dados de imagem codificado em LZW . São necessários 5 bytes para representar o pixel único que a imagem possui. O algoritmo de compactação não foi projetado para compactar um único byte muito bem.

  • Trailer GIF (1 byte)

    Um byte único com um valor hexadecimal de 3B( ;em ASCII) indica o final do GIF.

Com base nas estruturas necessárias para um GIF transparente, verifica-se que 43 bytes são quase tão pequenos quanto você pode obter.

Mas consegui descobrir um truque para torná-lo um pouco menor. É mencionado no padrão que é opcional ter uma tabela de cores global. Obviamente, é indefinido o que acontece quando você cria um GIF sem uma tabela de cores.

Quando você tem um índice de tabela de cores definido como transparente, no entanto, os decodificadores de GIF parecem não se importar com a inexistência de uma tabela de cores.

Então, mudei o descritor de tela lógica para indicar que não havia tabela de cores global e removi a tabela em si, economizando um total de seis bytes, diminuindo o tamanho do arquivo para meros 37 bytes.

Curiosamente, o Wordpress me deu uma lista adorável de mensagens de erro do GD reclamando que este não é um arquivo GIF válido, apesar do fato de o Firefox e o GIMP serem abertos e exibidos (ele é "exibido" quando é transparente?) bem.

Para torná-lo ainda menor, procurei o maior bloco “opcional” restante da imagem, a extensão do controle gráfico. Se você não precisa de transparência, esse bloco não é mais necessário e outros 8 bytes podem ser removidos.

Fonte: O menor GIF de todos os tempos .


1
De acordo com esse artigo, a variação de 37 bytes depende de um comportamento indefinido e, de fato, o autor menciona que o analisador de imagens do wordpress não pode lidar com isso. Embora provavelmente funcione na maioria dos navegadores, considero uma opção arriscada. Eu ficaria com a variação de 43 bytes desse mesmo artigo. Uma variante disso já foi postada acima . Veja também a discussão nos comentários sobre a resposta superior
Brian


6

Este é o menor que encontrei (26 bytes):

data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=

Isso aparece preto no IE11.
tomasz86

4

Estou usando os seguintes dados uri para obter uma imagem vazia: //:0


O Firefox 44 e o Internet Explorer 11 mostram a tag img alt. Você precisa usar uma das
opções

Isso é mais eficiente que uma solicitação / resposta para uma imagem?
231118 nu everest

No entanto, a validação não é válida
Lucian Davidescu

0

Para imagem vazia:

data:null

(será traduzido para src=(unknown))


Eu gosto disso em princípio, mas o validador w3c não aprova na prática: Erro: Dados com valor inválido: null para o atributo src no elemento img: Final prematuro do URI.
brennanyoung
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.