Automatyczne obrazy Retina dla witryn internetowych

104

W przypadku nowego Apple MacBook Pro z wyświetlaczem Retina, jeśli umieścisz „standardowy” obraz na swojej stronie internetowej, będzie on trochę niewyraźny. Musisz więc dostarczyć obraz siatkówki.

Czy istnieje sposób na automatyczne przełączanie się na @2xobrazy, tak jak robi to iOS (z Objective-C)? To, co znalazłem, to: CSS dla obrazów o wysokiej rozdzielczości na urządzeniach mobilnych i wyświetlaczach Retina , ale chciałbym znaleźć automatyczny proces dla wszystkich moich obrazów, bez CSS lub JavaScript .

Czy to możliwe?

AKTUALIZACJA
Chciałbym podkreślić ten interesujący artykuł zaproponowany przez @Paul D. Waite i interesującą dyskusję na ten temat, do której prowadzi Sebastian .

sty 267
źródło
6
retinajs.com
Stephan Bönnemann-Walenta
3
Możesz to zrobić po stronie serwera za pomocą PHP: retina-images.complexcompulsions.com
ReLeaf
2
@ michaelward82: w przypadku obrazów fotograficznych Daan Jobsis sugeruje, że można udostępniać obrazy o rozmiarze siatkówki każdemu bez większych rozmiarów plików niż obrazy bez siatkówki , poprzez zwiększenie stopnia kompresji JPG zastosowanej do obrazu. Fakt, że obraz jest wyświetlany w pomniejszeniu lub na wyświetlaczu siatkówki, często oznacza, że ​​artefakty kompresji nie są widoczne.
Paul D. Waite
1
Właściwie to nie jest złe , ale zastanawiałem się, czy jest jakaś sztuczka do użycia. W iOS jest to automatyczne ... dlatego o to pytam! :)
267 stycznia
2
Zwróć uwagę, że autor „sugerowanego interesującego artykułu” popełnił kilka dużych błędów, które są opisane tutaj: silev.org/test/Retina-resize.html - więc artykuł należy traktować z dużym przymrużeniem oka .
Sebastian,

Odpowiedzi:

147

Istnieje nowy atrybut dla tagu img, który umożliwia dodanie atrybutu src siatkówki, a mianowicie srcset. Nie potrzeba javascript ani CSS, nie ma podwójnego ładowania obrazów.

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

Obsługa przeglądarek: http://caniuse.com/#search=srcset

Inne zasoby:

ebuat3989
źródło
<img src = "LaunchAirportIcon.png" srcset = "[email protected] 2x">
malhal
7
To nie jest już tylko zestaw internetowy, obsługuje go również Edge i Firefox. caniuse.com/#search=srcset - czyli obecnie ~ 64% użytkowników na całym świecie. Następnie weź pod uwagę, że bardzo niewielu użytkowników hi-DPI będzie korzystać z nieobsługiwanych przeglądarek (IE i stary Android), i wreszcie, że jest to bezpieczne - użytkownicy bez wsparcia po prostu widzą normalny obraz DPI. Zdecydowanie myślę, że jest gotowy do użycia.
andrewb
1
Ponadto brak podwójnego ładowania jest ogromnym dobrodziejstwem. Oznacza to, że nigdy nie marnujesz niczyjej przepustowości.
andrewb
IE po raz kolejny zawodzi. Ale mimo to zgadzam się z @andrewb. Aby rozwinąć jego komentarz, podaję x2 w środku, srcwięc IE / Opera zawsze zażąda wyższej wersji DPI.
Ricky Boyce
1
To powinna być akceptowana odpowiedź. Jest to zdecydowanie najłatwiejsze rozwiązanie dla tego wątku.
Julien Le Coupanec
14

Istnieją różne rozwiązania, z których każde ma swoje zalety i wady. To, która z nich jest dla Ciebie najlepsza, zależy od różnych czynników, takich jak sposób zaprojektowania Twojej witryny internetowej, jakiego rodzaju technologii używają Twoi typowi użytkownicy itp. Pamiętaj, że wyświetlacze Retina nie są ograniczone do Macbooka Pro Retina i nadchodzących iMaców, ale obejmują również urządzenia mobilne, które mogą mieć własne potrzeby.

Problem jest również ściśle związany z obrazami w projektach responsywnych w ogóle. W rzeczywistości prawdopodobnie najlepiej jest zastosować ogólne techniki projektowania responsywnego zamiast projektowania pod kątem konkretnych urządzeń. W końcu technologia będzie się zmieniać także w przyszłości.

Niektóre z rozwiązań / dyskusji, które zauważyłem:

  • Wektory w miarę możliwości, w tym techniki CSS (gradienty, zaokrąglone rogi itp.), SVG i czcionki ikon.
  • Dostarczanie obrazów o wysokiej rozdzielczości („siatkówki”), ale bardziej je kompresuj (jakość JPEG), zgodnie z sugestią Yoav Weiss , lub pozwól sieciom komórkowym kompresować je, gdy są naprawdę potrzebne (np. Gdy są mobilne), zgodnie z sugestią Paula Boaga .
  • Obrazy adaptacyjne , (głównie) rozwiązanie po stronie serwera. Opiera się na pliku cookie przechowującym rozdzielczość ekranu, serwerze internetowym skonfigurowanym do obsługi obrazów ze skryptu PHP oraz nazwanym skrypcie, który odczytuje plik cookie i wyświetla odpowiedni obraz.
  • Szereg możliwości dobrze opisanych i omówionych w Smashing Magazine .
  • Podawanie tylko nieco wyższych rozdzielczości, aby nieco wygładzić obraz siatkówki, jak sugeruje film autorstwa Paula Boaga .
  • Technika @ 1,5x w A List Apart jest w zasadzie tym samym pomysłem.
  • W niedalekiej przyszłości <picture>tag może stać się rozwiązaniem wspieranym przez grupę roboczą W3C, a nawet Apple.
  • Technika JavaScript proponowany przez Jake Archebald .
  • Obszerne omówienie różnych technik na Smashing Magazine i problem w ogóle.

Jak pokazują inne odpowiedzi, istnieje jeszcze więcej technik - ale prawdopodobnie nie ma jeszcze najlepszych praktyk.

Zastanawiam się tylko, jak przetestować i debugować niektóre z tych technik bez posiadania odpowiednich urządzeń ...

bhell
źródło
11

Ponieważ nikt jeszcze nie wspomniał o tym, co oczywiste, opowiem o tym: tam, gdzie to możliwe, po prostu użyj SVG. Pojawiają się w pięknych rozdzielczościach siatkówki bez żadnego wysiłku.

Wsparcie dla tego jest dobre, ponieważ IE8 jest głównym dinozaurem, o który należy się martwić. Rozmiary plików spakowanych Gzip są często lepsze niż formaty bitmapowe (png / jpg), a obrazy są bardziej elastyczne; można je ponownie wykorzystać w różnych rozdzielczościach i zmienić ich styl, jeśli to konieczne, co oszczędza czas programowania i przepustowość pobierania.

svachalek
źródło
Podoba mi się twoja wskazówka! Jedyny problem svgdotyczy starszych przeglądarek.
267 stycznia
15
I przypadki, w których masz zdjęcia
Baumr
Rzeczywiście, są świetne, pod warunkiem, że masz wersję Vector obrazu, którego chcesz użyć, ale nie wierzę, że możesz zapisać normalne obrazy rastrowe jako SVG.
Chuck Le Butt
Nie ma „dobrego” sposobu na konwersję w tym kierunku, a więc „tam, gdzie to możliwe”. Ale z wyjątkiem witryn fotograficznych itp., Generalnie będziesz tworzyć zasoby artystyczne, więc polecam wykonanie ich jako wektorów, które można łatwo przekonwertować na raster, jeśli chcesz, w dowolnej rozdzielczości.
svachalek
SVG nie działa w przypadku zrzutów ekranu (np. Podczas dokumentowania funkcji interfejsu użytkownika).
Greg Brown
9

Oto mniej mieszania, którego używam, aby to osiągnąć dla obrazów tła. retina.js nie działa dla obrazów tła, jeśli używasz dotLess, ponieważ wymaga własnej mieszanki, która sama używa oceny skryptu, która nie jest obsługiwana w dotLess.

Sztuczka z tym wszystkim polega na uzyskaniu obsługi IE8. Nie można łatwo ustawić rozmiaru tła, więc przypadek podstawowy (zapytanie o media inne niż mobilne) musi być prostą, nieskalowaną ikoną. Zapytanie o media obsługuje wtedy przypadek siatkówki i może używać klasy rozmiaru tła, ponieważ siatkówka nigdy nie będzie używana w 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;
         }
}

Próbka użycia:

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

Wymaga to dwóch plików:

Gdzie 2xplik ma podwójną rozdzielczość dla siatkówki.

muzzamo
źródło
8

Po prostu udostępnij obrazy siatkówki wszystkim i ściśnij obraz do połowy jego natywnego rozmiaru wewnątrz elementu image. Powiedzmy, że twój obraz jest 400pxszeroki i wysoki - po prostu określ szerokość obrazu, 200pxaby wyglądał ostro w następujący sposób:

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

Jeśli twój obraz jest fotograficzny, prawdopodobnie możesz zwiększyć kompresję JPG na nim bez pogorszenia wyglądu, ponieważ artefakty kompresji JPG prawdopodobnie nie będą widoczne, gdy obraz jest wyświetlany pod adresem 2x: patrz http://blog.netvlies.nl/ design-interakcje / rewolucja-siatkówki /

webdev
źródło
1
Daan Jobsis sugeruje, że w przypadku obrazów fotograficznych nie musi to nawet skutkować większymi rozmiarami plików: patrz blog.netvlies.nl/design-interactie/retina-revolution
Paul D. Waite
Najlepiej byłoby jednak określić wysokość, aby przeglądarka mogła rozłożyć stronę przed pobraniem obrazu.
Paul D. Waite
8
Wydaje mi się, że nie jest to dobry pomysł, aby udostępnić większy i cięższy plik obrazu, jeśli nie jest to konieczne ...
267 stycznia
1
@ PaulD. Czekaj interesująco na początek i dokładnie na koniec! :)
267 stycznia
2
@ PaulD.Waite Zauważ, że autor podlinkowanego artykułu popełnił kilka dużych błędów, które są omówione tutaj: silev.org/test/Retina-resize.html - więc artykuł należy traktować z dużym przymrużeniem oka . Zwłaszcza fakt, że „nieskalowany obraz po prawej stronie” jest w rzeczywistości przeskalowany i nie można go tak naprawdę porównać z tym, którego rozdzielczość jest dokładnie podwojona (powiedz przeglądarce, aby pokazała odpowiednie obrazy w nowym oknie, a zobaczysz, co ja i autor tego drugiego artykułu ma na myśli)
Sebastian
1

jeśli jego obrazy tła, prostym sposobem na zrobienie tego jest:

    #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%; }
}

Innym prostym sposobem jest użycie tej metody:

Wystarczy wymienić:

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

z

<img src="[email protected]" alt="" width="200" height="100" />
SonnyP
źródło
1

Znalazłem ten interesujący sposób dostarczania obrazów w wielu rozdzielczościach.
W rzeczywistości wykorzystuje CSS, coś, czego chciałem uniknąć, i działa tylko w Safari i Chrome.
mówię oimage-set .

Oto przykład dostarczony przez Apple ( tutaj ):

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 */
}

Chcę też udostępnić te dwa linki:

sty 267
źródło
1

Za pomocą JSF można utworzyć niestandardowy znacznik Facelets, aby uniknąć konieczności dodawaniasrcset do każdego obrazu.

W swoim taglib.xmlmógłbyś mieć coś takiego:

<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>

Twój tag może wyglądać następująco:

<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>

Które można wykorzystać na przykład:

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

I wyrenderuje:

<img src="image.jpg"
     srcset="[email protected] 2x"/>
Jasper de Vries
źródło
0

Ten problem jest szczególnie trudny w przypadku responsywnych witryn, w których obrazy i obrazy mogą mieć różną szerokość w zależności od rozmiaru przeglądarki. Również w przypadku systemu CMS, w którym wielu redaktorów potencjalnie przesyła tysiące obrazów, wydawało mi się nierealne, aby prosić ludzi o przesyłanie specjalnie skompresowanych obrazów.

Napisałem więc skrypt, który bierze to pod uwagę, odpala na dole strony i po zakończeniu zmiany rozmiaru. Za każdym razem biorąc pod uwagę gęstość pikseli i rozmiar zajmowany przez obraz.

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

Krystyna 82
źródło
0

Jeśli nie denerwuje cię strach przed używaniem skryptu java, oto dobry artykuł http://www.highrobotics.com/articles/web/ready-for-retina.aspx . Ma bardzo proste rozwiązanie.

A przykład w JSFiddle jest wart tysiąca słów.

Za pomocą:

<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
źródło