Automatische Retina-Bilder für Websites

104

Wenn Sie mit dem neuen Apple MacBook Pro mit Retina-Display ein "Standard" -Bild auf Ihrer Website bereitstellen, wird es etwas unscharf. Sie müssen also ein Netzhautbild bereitstellen.

Gibt es eine Möglichkeit, automatisch zu @2xBildern zu wechseln , wie dies iOS (mit Objective-C) tut? Was ich gefunden habe, ist: CSS für hochauflösende Bilder auf Mobil- und Retina-Displays , aber ich wünschte, ich könnte einen automatischen Prozess für alle meine Bilder ohne CSS oder JavaScript finden .

Ist es möglich?

UPDATE
Ich möchte diesen interessanten Artikel hervorheben , der von @Paul D. Waite vorgeschlagen wurde, und eine interessante Diskussion darüber, die von Sebastian verlinkt wurde .

jan267
quelle
6
retinajs.com
Stephan Bönnemann-Walenta
3
Sie können es serverseitig mit PHP tun: retina-images.complexcompulsions.com
ReLeaf
2
@ michaelward82: Für fotografische Bilder schlägt Daan Jobsis vor, dass Sie Bilder in Retina-Größe für alle bereitstellen können, ohne dass Ihre Dateigröße größer ist als bei Bildern ohne Retina , indem Sie die auf das Bild angewendete JPG-Komprimierung erhöhen. Die Tatsache, dass das Bild entweder verkleinert oder auf einer Netzhautanzeige angezeigt wird, bedeutet häufig, dass die Komprimierungsartefakte nicht sichtbar sind.
Paul D. Waite
1
Eigentlich ist es nicht falsch , aber ich habe mich gefragt, ob es einen Trick gibt . In iOS ist es automatisch ... deshalb frage ich es! :)
Januar 267
2
Beachten Sie, dass der Autor des "vorgeschlagenen vorgeschlagenen Artikels" einige große Fehler gemacht hat, die hier beschrieben werden: silev.org/test/Retina-resize.html - daher muss der Artikel mit einem großen Salzkorn aufgenommen werden.
Sebastian

Antworten:

147

Für das img-Tag gibt es ein neues Attribut, mit dem Sie ein retina src-Attribut hinzufügen können, nämlich srcset. Kein Javascript oder CSS erforderlich, kein doppeltes Laden von Bildern.

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

Browser-Unterstützung: http://caniuse.com/#search=srcset

Andere Ressourcen:

ebuat3989
quelle
<img src = "LaunchAirportIcon.png" srcset = "[email protected] 2x">
Malhal
7
Dies ist nicht mehr nur ein Webkit, Edge & Firefox unterstützt es auch. caniuse.com/#search=srcset - also derzeit ~ 64% der Benutzer weltweit. Berücksichtigen Sie dann, dass nur sehr wenige Hi-DPI-Benutzer in den nicht unterstützten Browsern (IE & altes Android) arbeiten und dass dies ausfallsicher ist - Benutzer ohne Unterstützung sehen einfach ein normales DPI-Image. Denken Sie auf jeden Fall, dass es einsatzbereit ist.
Andrew
1
Auch kein doppeltes Laden ist ein großer Segen. Dies bedeutet, dass Sie niemals die Bandbreite von jemandem verschwenden.
Andrewb
IE noch einmal zu kurz. Trotzdem stimme ich @andrewb zu. Um auf seinem Kommentar aufzubauen, stelle ich das x2 im Internet zur Verfügung, srcsodass IE / Opera immer die höhere DPI-Version anfordert.
Ricky Boyce
1
Dies sollte die akzeptierte Antwort sein. Es ist bei weitem die einfachste Lösung für diesen Thread.
Julien Le Coupanec
14

Es gibt verschiedene Lösungen mit jeweils eigenen Vor- und Nachteilen. Welches für Sie am besten geeignet ist, hängt von verschiedenen Faktoren ab, z. B. davon, wie Ihre Website gestaltet ist, welche Technologie Ihre typischen Besucher verwenden usw. Beachten Sie, dass Retina-Displays nicht nur auf das Macbook Pro Retina und die kommenden iMacs beschränkt sind, sondern auch enthalten mobile Geräte, die ihre eigenen Bedürfnisse haben können.

Das Problem hängt auch eng mit Bildern in reaktionsschnellen Designs im Allgemeinen zusammen. In der Tat ist es wahrscheinlich am besten, generische reaktionsschnelle Designtechniken zu verwenden, anstatt für bestimmte Geräte zu entwerfen. Schließlich wird sich die Technologie auch in Zukunft ständig ändern.

Einige der Lösungen / Diskussionen, die ich notiert habe:

  • Vektoren, wo immer möglich, einschließlich CSS-Techniken (Verläufe, abgerundete Ecken usw.), SVG- und Symbolschriftarten.
  • Sie können hochauflösende Bilder ("Retina") bereitstellen, diese jedoch stärker komprimieren (JPEG-Qualität), wie von Yoav Weiss vorgeschlagen , oder sie von den Mobilfunknetzen komprimieren lassen, wenn sie wirklich benötigt werden (dh wenn sie mobil sind), wie von Paul Boag vorgeschlagen .
  • Adaptive Images , eine (meistens) serverseitige Lösung. Es basiert auf einem Cookie, in dem die Bildschirmauflösung gespeichert ist, einem Webserver, der zum Bereitstellen von Bildern aus einem PHP-Skript konfiguriert ist, und einem benannten Skript zum Lesen des Cookies und zum Bereitstellen des entsprechenden Bilds.
  • Eine Reihe von Möglichkeiten , die im Smashing Magazine gut beschrieben und diskutiert wurden .
  • Wie in einem Video von Paul Boag vorgeschlagen, werden nur geringfügig höhere Auflösungen verwendet, um die Darstellung der Netzhaut ein wenig zu glätten .
  • Die @ 1.5x-Technik auf A List Apart ist im Grunde die gleiche Idee.
  • In naher Zukunft wird das <picture>Tag möglicherweise zu einer Lösung, die von einer W3C-Arbeitsgruppe und sogar von Apple unterstützt wird.
  • Eine von Jake Archebald vorgeschlagene JavaScript-Technik .
  • Eine ausführliche Diskussion verschiedener Techniken im Smashing Magazine und dem Problem im Allgemeinen.

Wie die anderen Antworten zeigen, gibt es noch mehr Techniken - aber wahrscheinlich noch keine bewährten Methoden.

Ich frage mich, wie man einige dieser Techniken testet und debuggt, ohne dass die entsprechenden Geräte verfügbar sind ...

bhell
quelle
11

Da noch niemand das Offensichtliche erwähnt hat, werde ich es dort rausschweben: Wenn möglich, benutze einfach SVG. Sie erscheinen bei schönen Netzhautauflösungen ohne jegliche Anstrengung.

Die Unterstützung dafür ist gut, da IE8 der Hauptdinosaurier ist, über den man sich Sorgen machen muss. Gzipped-Dateigrößen sind oft besser als Bitmap-Formate (PNG / JPG) und die Bilder sind flexibler. Sie können sie mit unterschiedlichen Auflösungen wiederverwenden und bei Bedarf neu formatieren, was sowohl Entwicklungszeit als auch Download-Bandbreite spart.

Svachalek
quelle
Ich mag deinen Hinweis! Das einzige Problem svgist mit älteren Browsern.
Januar 267
15
Und Fälle, in denen Sie Fotos haben
Baumr
Sie sind in der Tat großartig, vorausgesetzt, Sie haben eine Vektorversion des Bildes, das Sie verwenden möchten, aber ich glaube nicht, dass Sie normale Rasterbilder als SVG speichern können.
Chuck Le Butt
Es gibt keinen "guten" Weg, um in diese Richtung zu konvertieren, also den "wo möglich". Mit Ausnahme von Fotoseiten usw. werden Sie im Allgemeinen Ihre Kunstobjekte erstellen. Ich würde daher empfehlen, sie als Vektoren zu erstellen, die bei jeder Auflösung problemlos in Raster konvertiert werden können, wenn Sie möchten.
Svachalek
SVG funktioniert nicht für Screenshots (z. B. beim Dokumentieren von UI-Funktionen).
Greg Brown
9

Hier ist das weniger Mixin, das ich verwende, um dies für Hintergrundbilder zu erreichen. retina.js funktioniert nicht für Hintergrundbilder, wenn Sie dotLess verwenden, da ein eigenes Mixin erforderlich ist, das selbst eine Skriptbewertung verwendet, die in dotLess nicht unterstützt wird.

Der Trick bei all dem ist, IE8-Unterstützung zu bekommen. Die Hintergrundgröße kann nicht einfach ermittelt werden, daher muss der Basisfall (nicht mobile Medienabfrage) ein einfaches, nicht skaliertes Symbol sein. Die Medienabfrage behandelt dann den Fall der Netzhaut und kann die Hintergrundgrößenklasse verwenden, da die Netzhaut im IE8 niemals verwendet wird.

.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;
         }
}

Anwendungsbeispiel:

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

Dafür müssen Sie zwei Dateien haben:

Wo die 2xDatei doppelte Auflösung für die Netzhaut ist.

Maulkorb
quelle
8

Stellen Sie einfach allen Retina-Bilder zur Verfügung und drücken Sie das Bild innerhalb des Bildelements auf die Hälfte seiner ursprünglichen Größe. Nehmen wir an, Ihr Bild ist 400pxbreit und hoch. Geben Sie einfach die Bildbreite 200pxan, damit es so scharf aussieht:

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

Wenn Ihr Bild fotografisch ist, können Sie wahrscheinlich die JPG-Komprimierung erhöhen, ohne es schlechter aussehen zu lassen, da die JPG-Komprimierungsartefakte wahrscheinlich nicht sichtbar sind, wenn das Bild angezeigt wird unter 2x: siehe http://blog.netvlies.nl/ Design-Interaktion / Netzhaut-Revolution /

webdev
quelle
1
Daan Jobsis schlägt vor, dass dies für fotografische Bilder nicht einmal zu größeren Dateien führen muss: siehe blog.netvlies.nl/design-interactie/retina-revolution
Paul D. Waite
Idealerweise sollten Sie jedoch eine Höhe angeben, damit der Browser die Seite vor dem Herunterladen des Bildes auslegen kann.
Paul D. Waite
8
Ich denke nicht, dass es eine großartige Idee ist, eine größere und schwerere Bilddatei
bereitzustellen,
1
@ PaulD.Waite interessant für das Erste und genau für das Letzte! :)
Januar 267
2
@ PaulD.Waite Beachten Sie, dass der Autor des verlinkten Artikels einige große Fehler gemacht hat, die hier diskutiert werden: silev.org/test/Retina-resize.html - daher muss der Artikel mit einem großen Körnchen Salz aufgenommen werden. Insbesondere die Tatsache, dass das "nicht skalierte Bild rechts" tatsächlich skaliert ist und daher nicht wirklich mit dem verglichen werden kann, dessen Auflösung genau verdoppelt ist (sagen Sie Ihrem Browser, dass er die richtigen Bilder in einem neuen Fenster anzeigen soll, und Sie werden sehen, was ich und der Autor dieses anderen Artikels bedeutet)
Sebastian
1

Wenn seine Hintergrundbilder eine einfache Möglichkeit sind, dies zu tun, ist:

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

Eine andere einfache Möglichkeit ist die Verwendung dieser Methode:

Einfach ersetzen:

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

mit

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

Ich habe diesen interessanten Weg gefunden, um Bilder mit mehreren Auflösungen bereitzustellen.
Es verwendet tatsächlich CSS, was ich vermeiden wollte, und funktioniert nur in Safari und Chrome.
Ich spreche über image-set.

Hier ist ein Beispiel von Apple ( hier ):

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

Ich möchte auch diese beiden Links teilen:

jan267
quelle
1

Mit JSF können Sie ein benutzerdefiniertes Facelets-Tag erstellen , um den Aufwand zu vermeiden srcset, dass Sie jedem Bild etwas hinzufügen müssen.

In deinem taglib.xmlkönntest du so etwas haben wie:

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

Und Ihr Tag könnte ungefähr so ​​aussehen:

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

Welches könnte verwendet werden wie:

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

Und wird rendern:

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

Dieses Problem ist besonders schwierig bei reaktionsfähigen Websites, bei denen das Bild je nach Browsergröße unterschiedlich breit sein kann. Auch wenn es sich um ein CMS handelt, bei dem mehrere Editoren möglicherweise Tausende von Bildern hochladen, erschien es mir unrealistisch, Leute zu bitten, speziell komprimierte Bilder hochzuladen.

Also habe ich ein Skript geschrieben, das dies berücksichtigt. Es wird am Ende der Seite ausgelöst und beim Ändern der Größe beendet. Jedes Mal unter Berücksichtigung der Pixeldichte und der Größe, die das Bild einnimmt.

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

Keegan 82
quelle
0

Wenn Sie nicht aus Angst vor der Verwendung von Java-Skript frustriert sind, finden Sie hier einen guten Artikel: http://www.highrobotics.com/articles/web/ready-for-retina.aspx . Es hat eine sehr einfache Lösung.

Und das Beispiel in JSFiddle sagt mehr als tausend Worte.

Verwenden von:

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