Imagens Retina automáticas para sites

104

Com o novo Apple MacBook Pro com tela retina, se você fornecer uma imagem "padrão" em seu site, ela ficará um pouco confusa. Portanto, você deve fornecer uma imagem da retina.

Existe uma maneira de alternar automaticamente para @2ximagens, como o iOS (com Objective-C) faz? O que encontrei é: CSS para imagens de alta resolução em telas mobile e retina , mas gostaria de poder encontrar um processo automático para todas as minhas imagens, sem CSS ou JavaScript .

É possível?

ATUALIZAÇÃO
Gostaria de enfatizar este artigo interessante sugerido por @Paul D. Waite e uma discussão interessante sobre ele linkada por Sebastian .

jan267
fonte
6
retinajs.com
Stephan Bönnemann-Walenta
3
Você pode fazer isso do lado do servidor com PHP: retina-images.complexcompulsions.com
ReLeaf
2
@ michaelward82: para imagens fotográficas, Daan Jobsis sugere que você pode veicular imagens em tamanho de retina para todos sem que os tamanhos de seus arquivos sejam maiores do que imagens não retina , aumentando a quantidade de compressão JPG aplicada à imagem. O fato de a imagem ser exibida em escala reduzida ou em uma tela de retina geralmente significa que os artefatos de compactação não são visíveis.
Paul D. Waite
1
Na verdade não está errado , mas eu queria saber se havia algum truque para usar. No iOS é automático ... é por isso que estou perguntando! :)
janeiro 267
2
Observe que o autor do "artigo interessante sugerido" cometeu alguns grandes erros que são descritos aqui: silev.org/test/Retina-resize.html - então o artigo deve ser considerado com cautela .
Sebastian

Respostas:

147

Há um novo atributo para a tag img que permite adicionar um atributo retina src, chamado srcset. Não é necessário javascript ou CSS, nem carregamento duplo de imagens.

<img src="low-res.jpg" srcset="high-res.jpg 2x">

Suporte para navegador: http://caniuse.com/#search=srcset

Outros recursos:

ebuat3989
fonte
<img src = "LaunchAirportIcon.png" srcset = "[email protected] 2x">
malhal
7
Este não é mais apenas um webkit, Edge e Firefox também o suportam. caniuse.com/#search=srcset - atualmente, aproximadamente 64% dos usuários globalmente. Em seguida, leve em consideração que muito poucos usuários de hi-DPI estarão em navegadores sem suporte (IE e Android antigo) e, por último, que é à prova de falhas - usuários sem suporte simplesmente veem uma imagem DPI normal. Definitivamente acho que está pronto para uso.
andrewb de
1
Além disso, nenhum carregamento duplo é uma grande vantagem. Isso significa que você nunca desperdiça a largura de banda de ninguém.
andrewb de
IE, mais uma vez, aquém. Mas, apesar disso, concordo com @andrewb. Para desenvolver seu comentário, estou fornecendo o x2 dentro do srcIE / Opera sempre solicitará a versão DPI superior.
Ricky Boyce
1
Esta deve ser a resposta aceita. É de longe a solução mais fácil para este tópico.
Julien Le Coupanec
14

Existem diferentes soluções, cada uma com seus prós e contras. Qual é o melhor para você depende de vários fatores, como a forma como seu site foi projetado, que tipo de tecnologia seus visitantes típicos estão usando, etc. Observe que as telas de retina não se limitam ao Macbook Pro Retina e aos próximos iMacs, mas também incluem dispositivos móveis, que podem ter suas próprias necessidades.

O problema também está intimamente relacionado a imagens em designs responsivos em geral. Na verdade, provavelmente é melhor utilizar técnicas genéricas de design responsivo, em vez de projetar para dispositivos específicos. Afinal, a tecnologia também continuará mudando o tempo todo no futuro.

Algumas das soluções / discussões que observei:

  • Vetores sempre que possível, incluindo técnicas CSS (gradientes, cantos arredondados, etc.), SVG e fontes de ícone.
  • Servir imagens de alta resolução ("retina"), mas compactá-las mais (qualidade JPEG), conforme sugerido por Yoav Weiss , ou deixar que as redes móveis as compactem quando realmente necessário (ou seja, quando móveis), conforme sugerido por Paul Boag .
  • Adaptive Images , uma solução (principalmente) do lado do servidor. É baseado em um cookie que armazena a resolução da tela, um servidor web configurado para servir imagens de um script PHP e um script nomeado para ler o cookie e servir a imagem apropriada.
  • Um monte de possibilidades bem descritas e discutidas na Smashing Magazine .
  • Servindo em resoluções um pouco mais altas para suavizar um pouco a representação da retina, como sugerido em um vídeo de Paul Boag .
  • A técnica @ 1.5x em A List Apart é basicamente a mesma ideia.
  • Em um futuro próximo, a <picture>tag pode se tornar uma solução apoiada por um grupo de trabalho do W3C e até mesmo da Apple.
  • Uma técnica JavaScript proposta por Jake Archebald .
  • Uma extensa discussão de diferentes técnicas na Smashing Magazine e o problema em geral.

Como mostram as outras respostas, existem ainda mais técnicas - mas provavelmente nenhuma prática recomendada ainda.

Uma coisa que me pergunto é como testar e depurar algumas dessas técnicas, sem ter o (s) respectivo (s) dispositivo (s) disponível (is) ...

bhell
fonte
11

Uma vez que ninguém mencionou o óbvio ainda, vou colocá-lo por aí: onde possível, apenas use SVG. Eles aparecem em belas resoluções de retina sem nenhum esforço.

O suporte para isso é bom, com o IE8 sendo o principal dinossauro com que se preocupar. Os tamanhos de arquivo compactados geralmente são melhores do que os formatos de bitmap (png / jpg) e as imagens são mais flexíveis; você pode reutilizá-los em diferentes resoluções e reformulá-los se necessário, o que economiza tempo de desenvolvimento e largura de banda de download.

svachalek
fonte
Eu gosto da sua dica! O único problema svgé com navegadores mais antigos.
janeiro 267
15
E casos em que você tem fotos
Baumr
Na verdade, eles são ótimos, desde que você tenha uma versão vetorial da imagem que deseja usar, mas não acredito que você possa salvar imagens raster normais como SVG.
Chuck Le Butt
Não existe uma maneira "boa" de converter nessa direção, portanto, o "sempre que possível". Mas, com exceção de sites de fotografia etc., você geralmente criará seus ativos de arte, então eu recomendo tê-los feitos como vetores, que podem ser facilmente convertidos para raster, se desejar, em qualquer resolução.
svachalek
O SVG não funciona para capturas de tela (por exemplo, ao documentar recursos da IU).
Greg Brown de
9

Aqui está o menos mixin que eu uso para conseguir isso para imagens de fundo. retina.js não funciona para imagens de fundo se você estiver usando dotLess, uma vez que requer seu próprio mixin que usa avaliação de script que não é compatível com dotLess.

O truque com tudo isso é obter suporte para o IE8. Ele não pode definir o tamanho do plano de fundo facilmente, então o caso base (consulta de mídia não móvel) deve ser um ícone simples e não dimensionado. A consulta de mídia então lida com o caso de retina e é livre para usar a classe de tamanho de plano de fundo, já que a retina nunca será usada no IE8.

.retina-background-image( @path, @filename,@extension, @size )
{
     .background-size( cover );
     background-image: url( "@{path}@{filename}@{extension}" );
         @media only screen and ( -webkit-min-device-pixel-ratio: 2 ),
                only screen and ( -moz-min-device-pixel-ratio: 2 ),
                only screen and ( -o-min-device-pixel-ratio: 2/1 ),
                only screen and ( min-device-pixel-ratio: 2 )
         {
             background-image:url( "@{path}@{filename}@x2@{extension}" );
             background-size:@size @size;
         }
}

Amostra de uso:

.retina-background-image( "../references/Images/", "start_grey-97_12", ".png", 12px );

Isso requer que você tenha dois arquivos:

Onde o 2xarquivo tem resolução dupla para retina.

muzzamo
fonte
8

Basta fornecer imagens de retina para todos e comprimir a imagem até a metade de seu tamanho original dentro do elemento de imagem. Digamos que sua imagem seja 400pxlarga e alta - apenas especifique a largura da imagem 200pxpara torná-la nítida assim:

<img src="img.jpg" width="200px" height="200px" />

Se a sua imagem for fotográfica, você provavelmente pode aumentar a compactação JPG nela sem torná-la pior, porque os artefatos de compactação JPG provavelmente não serão visíveis quando a imagem for exibida em 2x: consulte http://blog.netvlies.nl/ design-interactie / retina-revolution /

webdev
fonte
1
Daan Jobsis sugere que, para imagens fotográficas, isso nem precisa resultar em tamanhos de arquivo maiores: consulte blog.netvlies.nl/design-interactie/retina-revolution
Paul D. Waite
O ideal, porém, é especificar uma altura, para que o navegador possa definir o layout da página antes do download da imagem.
Paul D. Waite
8
Não acho que seja uma boa ideia fornecer um arquivo de imagem maior e mais pesado se não for necessário ...
jan267
1
@ PaulD.Waite interessante para a primeira coisa e exatamente para o final! :)
jan267
2
@ PaulD.Waite Observe que o autor do artigo vinculado cometeu alguns grandes erros que são discutidos aqui: silev.org/test/Retina-resize.html - portanto, o artigo deve ser considerado com cautela . Especialmente o fato de que a "imagem fora de escala à direita" é de fato dimensionada e, portanto, não pode realmente ser comparada com aquela cuja resolução é exatamente duplicada (diga ao seu navegador para mostrar as imagens certas em uma nova janela e você verá o que eu e o autor desse outro artigo quer dizer)
Sebastian
1

se suas imagens de fundo, uma maneira simples de fazer isso é:

    #image { background: url(image.png); }

@media only screen and (-webkit-min-device-pixel-ratio: 2),
       only screen and (-moz-min-device-pixel-ratio: 2),
       only screen and (-o-min-device-pixel-ratio: 2/1),
       only screen and (min-device-pixel-ratio: 2) {
           #image { background: url([email protected]); background-size: 50%; }
}

outra maneira simples é usar este método:

Basta substituir:

<img src="image.jpg" alt="" width="200" height="100" />

com

<img src="[email protected]" alt="" width="200" height="100" />
SonnyP
fonte
1

Eu descobri essa maneira interessante de fornecer imagens de resolução múltipla.
Na verdade, ele usa CSS, algo que eu queria evitar, e funciona apenas no Safari e no Chrome.
Estou falando sobre image-set.

Aqui está um exemplo , fornecido pela Apple ( aqui ):

header {
    background: -webkit-image-set( url(images/header.jpg)    1x,
                                   url(images/header_2x.jpg) 2x);
    height: 150px; /* height in CSS pixels */
    width: 800px; /* width in CSS pixels */
}

Quero compartilhar também estes dois links:

jan267
fonte
1

Com JSF você pode criar uma tag Facelets personalizada para evitar a confusão de ter que adicionar srcseta cada imagem.

No seu, taglib.xmlvocê poderia ter algo como:

<tag>
  <tag-name>img</tag-name>
  <source>tags/img.xhtml</source>
  <attribute>
    <name>src2x</name>
    <required>true</required>
    <type>java.lang.String</type>
  </attribute>
</tag>

E sua tag pode ser semelhante a:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
                xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

  <img src="#{fn:replace(src2x, '@2x', '')}"
       srcset="#{src2x} 2x"/>

</ui:composition>

Que pode ser usado como:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:myTag="http://your.com/namespace-of-taglib">
  <myTag:src2x="[email protected]"/>
</html>

E irá renderizar:

<img src="image.jpg"
     srcset="[email protected] 2x"/>
Jasper de Vries
fonte
0

Esse problema é especialmente complicado com sites responsivos, nos quais uma imagem pode ter largura variável, dependendo do tamanho do navegador. Além disso, ao lidar com um CMS onde vários editores estão potencialmente enviando milhares de imagens, parecia irreal para mim pedir às pessoas que enviassem imagens especialmente compactadas.

Então eu escrevi um script que leva isso em consideração, ele dispara na parte inferior da página e ao final do redimensionamento. Cada vez levando em conta a densidade de pixels e o tamanho que a imagem está ocupando.

http://caracaldigital.com/retina-handling-code/

Keegan 82
fonte
0

Se você não está frustrado com o medo de usar java-script, aqui está um bom artigo http://www.highrobotics.com/articles/web/ready-for-retina.aspx . Tem solução muito simples.

E o exemplo em JSFiddle vale mais que mil palavras.

Usando:

<img onload="getImgSrc(this,'image_x1.png')" width="100" height="100" />

JS:

/* RETINA READY IMG SRC */
function getImgSrc(img, src) {
    var srcResult = src;
    // if high-res screen then change _x1 on _x2
    if (window.devicePixelRatio > 1 && 
        src.indexOf("_x1.")>=0) {
          srcResult = src.replace("_x1.", "_x2.");
    }
    img.onload = null; //protect from second rasing
    img.src = srcResult;    
}

$(document).ready(function(){
  // fire onload trigger on IMG tags that have empty SRC attribute
  var images = $('img:not([src=""])');
    images.each(function(i) {
        $(this).trigger('onload');            
    });
});
Artru
fonte