Imagens fáceis de DPI alto

Telas com alta densidade de pixels estão se tornando o padrão rapidamente. Os criadores de conteúdo precisam se adaptar a esse fato. Este é um breve guia sobre como veicular imagens de alta qualidade na Web atualmente, sem polyfills, JavaScript, truques de CSS e recursos do navegador que ainda não foram implementados. Resumindo: sem mudanças drásticas no seu fluxo de trabalho.

Atualmente, há muitas propostas de imagem responsiva, e muitas delas envolvem mudanças significativas para o desenvolvedor da Web. O atributo <img> srcset de faixa padrão é difícil de implementar, especialmente com a complexidade da seleção extra baseada na janela de visualização do srcset:

banner-HD.jpeg 2x, banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x

Embora a propriedade CSS image-set use apenas devicePixelRatio para decidir qual imagem carregar, ela ainda força os desenvolvedores a criar muitas marcações extras para cada imagem.

Outras propostas, como o elemento <picture>, são ainda mais detalhadas. Além disso, eles não são de rastreamento padrão, portanto, sua disponibilidade onipresente está ainda maior do que o atributo srcset. As soluções de JavaScript e do lado do servidor são as únicas outras alternativas, mas essas abordagens têm as próprias desvantagens, conforme abordado em outros artigos.

Este artigo abordará vários usos de imagens comumente encontradas na Web e proporá soluções simples que funcionam em telas com alta densidade de pixels e também nas telas comuns. Para os fins desta discussão, qualquer dispositivo que informe um window.devicePixelRatio maior que 1 pode ser considerado um DPI alto, já que isso significa que os pixels CSS não são iguais aos pixels do dispositivo e que as imagens estão sendo redimensionadas.

Veja um resumo:

  • Use CSS/SVG em vez de imagens de varredura, se possível.
  • Use imagens otimizadas para telas de alta densidade por padrão.
  • Use PNGs para desenhos simples e pixel art (por exemplo, logotipos).
  • Use JPEGs compactados para imagens com várias cores (por exemplo, fotos).
  • Sempre defina tamanhos explícitos (usando CSS ou HTML) em todos os elementos de imagem.

Desenhos simples e pixel art

Imagens pequenas geralmente podem ser totalmente evitadas usando recursos CSS ou SVG. Não é necessário usar imagens para cantos arredondados, por exemplo, já que a propriedade border-radius do CSS é amplamente aceita. Da mesma forma, fontes personalizadas são amplamente aceitas, portanto, não é recomendável usar texto "com imagens".

No entanto, em alguns casos, como logotipos, uma imagem pode ser a única maneira de avançar. Por exemplo, este logotipo do Google Chrome tem um tamanho natural de 256 x 256. Em uma tela Retina, é possível ver a serrilhado nas diagonais e curvas, o que fica grosso e ruim, principalmente em comparação com o texto renderizado com nitidez:

Chrome 1x
PNG 1x

Dimensões naturais: 256x256px, tamanho do recurso: 31 kB, formato: PNG

Convencido? Bom. Agora, vamos usar uma imagem de alta densidade. Você pode ficar tentado a economizar espaço armazenando seu logotipo como um JPEG, mas essa pode não ser uma boa ideia, já que salvar logotipos e outros gráficos em um formato com perda tende a introduzir artefatos. Nesse caso, exagerei o problema usando uma compressão muito alta, mas observei as faixas nos gradientes, as manchas em fundos brancos e as linhas bagunçadas:

Google Chrome 2x
jpeg 2x

Dimensões naturais: 512x512px, tamanho do recurso: 13 kB, formato: JPEG

Para imagens relativamente pequenas, use o dobro de PNGs. A diferença de tamanho entre um PNG de 1x e 2x geralmente é muito alta (neste caso, 52 KB). No entanto, no caso de um logotipo, ele é o rosto do seu site e a primeira coisa que os visitantes vão ver. Ao reduzir demais a qualidade em troca do tamanho, ele também será a última coisa que os visitantes verão.

Veja o logotipo do Chrome em toda a sua glória, reduzido para metade das dimensões naturais para telas 2x:

Google Chrome 2x
PNG 2

Dimensões naturais: 512x512px, tamanho do recurso: 83 kB, formato: PNG

A marcação para fazer a renderização acima é a seguinte:

<img src="chrome2x.png" style="width: 256px; height: 256px;"/>

Especifiquei uma largura e uma altura na imagem. Isso é necessário porque o tamanho natural da imagem é de 512 pixels. Isso também é bom para o desempenho, porque o mecanismo de renderização tem uma boa compreensão do tamanho do elemento e não precisa se esforçar muito para calculá-lo.

Uma otimização possível que pode funcionar é reduzir o PNG de 24 bits para um de 8 bits com paleta. Isso funciona para imagens com poucas cores, incluindo o logotipo do Chrome. Para fazer essa otimização, use uma ferramenta como http://pngquant.org/ (em inglês). Você pode notar um pouco de faixas, mas esse arquivo tem apenas 13 kB, o que representa uma economia de tamanho impressionante de 6x em comparação com o PNG original de 512 x 512.

Chrome 2 de 8 bits
PNG 2 de 8 bits

Dimensões naturais: 512x512px, tamanho do recurso: 13 kB, formato: PNG, 8-bit palette

Imagens com várias cores

Escrevi um artigo sobre HTML5Rocks que pesquisava várias técnicas diferentes de imagem responsiva e fiz algumas pesquisas sobre a compactação de JPEG 1x e 2x e a comparação dos tamanhos resultantes e da qualidade visual. Confira um desses blocos do artigo acima:

.

Rotulei as imagens com o nível de compactação (indicado pela qualidade JPEG), o tamanho (em bytes) e minha opinião subjetiva sobre a fidelidade visual comparativa (classificada por números). O interessante aqui é que a imagem de 2x altamente compactada (rotulada como 3) é menor em tamanho e parece melhor do que a imagem de 1x não compactada (rotulada como 4). Em outras palavras, entre as imagens 4 e 3, conseguimos melhorar a qualidade da imagem duplicando cada dimensão e aumentando significativamente a compactação e, ao mesmo tempo, reduzindo o tamanho em 2 KB.

Compactação, dimensões e qualidade visual

Quero entender melhor as compensações entre nível de compactação, dimensões da imagem, qualidade visual e tamanho da imagem. Realizei um estudo com a seguinte hipótese baseada no estudo acima:

Hipótese

Com compactação suficiente, uma imagem de 2x terá a mesma aparência da mesma imagem em tamanho 1x em alguma outra compactação (menor). No entanto, nesse caso, a imagem de 2x altamente compactada será menor em tamanho do que a imagem de 1x.

Processar

  • Com uma imagem de 2x, gere a de 1x.
  • Compacte as duas imagens em vários níveis.
  • Crie uma página de teste que mostre os dois conjuntos de imagens lado a lado.
  • Nos dois conjuntos, encontre o lugar em que as imagens são equivalentes.
  • Observe tamanhos de imagem e níveis de compactação equivalentes.
  • Teste em telas 1x e 2x.

Criei um app de comparação de imagens lado a lado semelhante à visualização de comparação do Lightroom. A intenção é mostrar imagens 1x e 2x lado a lado, mas também permitir que você amplie qualquer seção da imagem para ver mais detalhes. Você também pode selecionar entre os formatos JPEG e WebP e mudar a qualidade da compactação para conferir comparações de tamanho de arquivo e qualidade da imagem. A ideia é ajustar as configurações em várias imagens, descobrir quais benefícios de qualidade da compactação, dimensionamento e formato você quer usar em relação à qualidade da imagem e usar essa configuração para todas as imagens.

Captura de tela da comparação

A ferramenta em si está disponível para uso. Para aumentar o zoom da imagem, selecione uma subárea.

Análise

Vou dizer antecipadamente que a qualidade da imagem é algo subjetivo. Além disso, seu caso de uso específico provavelmente ditará onde suas prioridades estão no espectro de fidelidade visual vs. tamanho de arquivo. Além disso, diferentes tipos de recursos de imagem reagem de maneira diferente à qualidade de dimensionamento e compactação. Portanto, uma solução única para todos pode não funcionar aqui. O objetivo da ferramenta é ajudar você a criar uma intuição sobre compressões, escalas e formatos de qualidade de imagem.

Ao brincar com o recurso de zoom de imagens, algumas coisas ficaram evidentes para mim. Em primeiro lugar, prefiro usar quality=30 dpr=2x em vez de quality=90 dpr=1x para aumentar os detalhes. Essas imagens também são comparáveis em tamanho de arquivo. No caso do plano, a imagem compactada de 2x é de 76 kB enquanto a de 1x não compactada é de 80 kB.

As exceções a essa regra são imagens altamente compactadas (quality<30) com gradientes. Eles tendem a apresentar faixas de cores, que são igualmente ruins, independente da escala da imagem. As amostras de pássaros e carros encontradas na ferramenta são exemplos disso.

As imagens WebP parecem muito mais limpas do que JPEG, especialmente em baixos níveis de compressão. Essas faixas de cor parecem ser menos um problema. Por fim, as imagens WebP são muito mais compactas.

Advertências e aletas

Deixar as imagens com boa aparência em telas de alta densidade é apenas metade dos problemas relacionados a imagens causados por uma enorme variação nas telas. Em alguns casos, convém disponibilizar imagens totalmente diferentes, dependendo do tamanho da janela de visualização. Por exemplo, a foto de rosto de Obama pode ser adequada para uma tela do tamanho de um telefone, mas o suporte à frente dele e a bandeira atrás dele e alguns podem ser mais adequados para uma tela de laptop.

Evitei deliberadamente esse tópico de "direção da arte" para me concentrar apenas em imagens de alto DPI. Esse problema pode ser resolvido com várias abordagens diferentes: consultas de mídia e imagens de plano de fundo usando JavaScript, alguns recursos novos, como image-set, ou no servidor. Este tópico é abordado em Imagens com DPI alto para densidades de pixel variáveis.

Assinarei com alguns problemas em aberto:

  • Efeitos da alta compactação no desempenho. Quais são as penalidades de decodificar imagens altamente compactadas?
  • Quais são as penalidades de performance de ter que redimensionar uma imagem quando uma imagem de 2x é carregada em uma tela de 1x?

Para resumir, opte por CSS e SVG em vez de usar imagens de varredura. Se imagens de varredura forem estritamente necessárias, use PNGs para imagens com paletas limitadas e muitas cores sólidas e JPEGs para imagens com muitas cores e gradientes. O melhor dessa abordagem é que sua marcação permanece praticamente inalterada. O desenvolvedor da Web só precisa gerar o dobro de recursos e dimensionar suas imagens corretamente no DOM.

Para saber mais, confira o artigo de Scott Jehl sobre um tópico semelhante. Que suas imagens pareçam nítidas e seu uso de dados móveis seja baixo!