Автоматические изображения Retina для веб-сайтов


104

С новым Apple MacBook Pro с дисплеем Retina, если вы разместите на своем веб-сайте «стандартное» изображение, оно будет немного нечетким. Итак, вы должны предоставить изображение сетчатки.

Есть ли способ автоматически переключаться на @2xизображения, как это делает iOS (с Objective-C)? Я обнаружил: CSS для изображений с высоким разрешением на мобильных устройствах и дисплеях Retina , но я хотел бы найти автоматический процесс для всех моих изображений без CSS или JavaScript .

Является ли это возможным?

ОБНОВЛЕНИЕ
Я хотел бы выделить эту интересную статью, предложенную @Paul D. Waite, и интересную дискуссию об этом, связанную с Себастьяном .



3
Вы можете сделать это на стороне сервера с помощью PHP: retina-images.complexcompulsions.com
ReLeaf

2
@ michaelward82: для фотографических изображений Даан Джобсис предлагает, чтобы вы могли показывать изображения размером с сетчатку всем, при этом размер ваших файлов не был бы больше, чем изображения без сетчатки , путем увеличения степени сжатия JPG, применяемого к изображению. Тот факт, что изображение отображается либо в уменьшенном масштабе, либо на дисплее сетчатки, часто означает, что артефакты сжатия не видны.
Пол Д. Уэйт,

1
На самом деле это не так , но мне было интересно, есть ли какой-нибудь трюк . В iOS автомат ... поэтому и спрашиваю! :)
jan267 06

2
Обратите внимание, что автор «предложенной интересной статьи» допустил несколько серьезных ошибок, которые описаны здесь: silv.org/test/Retina-resize.html - поэтому к статье следует относиться с большой долей скептицизма .
Себастьян

Ответы:


148

Для тега img появился новый атрибут, который позволяет добавлять атрибут src retina, а именно srcset. Никакого javascript или CSS, никакой двойной загрузки изображений.

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

Поддержка браузера: http://caniuse.com/#search=srcset

Другие источники:


<img src = "LaunchAirportIcon.png" srcset = "LaunchAirportIcon@2x.png 2x">
Malhal

7
Это уже не просто webkit, Edge и Firefox также его поддерживают. caniuse.com/#search=srcset - в настоящее время ~ 64% пользователей во всем мире. Затем примите во внимание, что очень немногие пользователи hi-DPI будут использовать неподдерживаемые браузеры (IE и старый Android), и, наконец, что это безотказно - пользователи без поддержки просто видят обычное изображение DPI. Определенно думаю, что он готов к использованию.
Эндрюб

1
Кроме того, отсутствие двойной загрузки - огромное благо. Это означает, что вы никогда не теряете чью-либо пропускную способность.
andrewb

IE снова терпит неудачу. Но, несмотря на это, я согласен с @andrewb. Чтобы основываться на его комментарии, я предоставляю x2 внутри, srcпоэтому IE / Opera всегда будет запрашивать более высокую версию DPI.
Рики Бойс

1
Это должен быть принятый ответ. Это, безусловно, самое простое решение для этой темы.
Жюльен Ле Купанек,

14

Существуют разные решения, каждое из которых имеет свои плюсы и минусы. Какой из них лучше всего подходит для вас, зависит от различных факторов, таких как дизайн вашего веб-сайта, какие технологии используют ваши типичные посетители и т. Д. Обратите внимание, что дисплеи Retina не ограничиваются Macbook Pro Retina и грядущими iMac, но также включают мобильные устройства, у которых могут быть свои потребности.

Проблема также тесно связана с изображениями в адаптивном дизайне в целом. Фактически, вероятно, лучше использовать общие методы адаптивного дизайна, а не проектировать для конкретных устройств. В конце концов, и в будущем технологии будут постоянно меняться.

Некоторые из решений / обсуждений, которые я отметил:

  • Векторы, где это возможно, включая методы CSS (градиенты, закругленные углы и т. Д.), SVG и шрифты значков.
  • Предоставлять изображения с высоким разрешением («сетчатка»), но сжимать их больше (качество JPEG), как предлагает Йоав Вайс , или позволять мобильным сетям сжимать их, когда это действительно необходимо (например, когда мобильно), как предлагает Пол Боаг .
  • Адаптивные изображения , (в основном) серверное решение. В его основе лежит файл cookie, в котором хранится разрешение экрана, веб-сервер, настроенный для обслуживания изображений из сценария PHP, и именованный сценарий для чтения файла cookie и предоставления соответствующего изображения.
  • Куча возможностей, хорошо описанных и обсуждаемых в Smashing Magazine .
  • Обслуживание чуть более высокого разрешения, чтобы немного сгладить изображение сетчатки, как это было предложено в видео Полом Боагом .
  • Техника @ 1.5x в A List Apart - это в основном та же идея.
  • В ближайшем будущем <picture>тег может стать решением, поддерживаемым рабочей группой W3C и даже Apple.
  • Метод JavaScript , предложенный Jake Archebald .
  • Широкое обсуждение различных методов на Smashing Magazine и проблема в целом.

Как показывают другие ответы, есть еще больше методов, но, вероятно, пока нет лучшей практики.

Мне интересно, как тестировать и отлаживать некоторые из этих методов, не имея соответствующих устройств ...


11

Поскольку никто еще не упомянул очевидное, я напомню об этом: где возможно, просто используйте SVG. Они появляются в прекрасном разрешении сетчатки без каких-либо усилий.

Поддержка его хороша, поскольку IE8 - главный динозавр, о котором нужно беспокоиться. Размеры файлов в формате Gzip часто лучше, чем в растровых форматах (png / jpg), а изображения более гибкие; вы можете повторно использовать их в разных разрешениях и при необходимости изменить их стиль, что сэкономит время на разработку и загрузку.


Мне нравится твой намек! Единственная проблема svgсвязана с более старыми браузерами.
jan267

15
И случаи, когда у вас есть фотографии
Баумр

Действительно, они великолепны, если у вас есть векторная версия изображения, которое вы хотите использовать, но я не верю, что вы можете сохранять обычные растровые изображения в формате SVG.
Chuck Le Butt

Не существует «хорошего» способа конвертировать в этом направлении, следовательно, «там, где это возможно». Но за исключением сайтов с фотографиями и т. Д. Вы, как правило, собираетесь создавать свои художественные активы, поэтому я бы рекомендовал делать их в виде векторов, которые можно легко преобразовать в растр, если хотите, с любым разрешением.
svachalek

SVG не работает для снимков экрана (например, при документировании функций пользовательского интерфейса).
Грег Браун

9

Вот меньшее количество миксинов, которые я использую для этого для фоновых изображений. retina.js не работает с фоновыми изображениями, если вы используете dotLess, поскольку для этого требуется собственный миксин, который сам использует оценку скрипта, которая не поддерживается в dotLess.

Уловка со всем этим заключается в том, чтобы получить поддержку IE8. Он не может легко сделать background-size, поэтому базовым случаем (немобильный медиа-запрос) должен быть простой немасштабируемый значок. Затем медиа-запрос обрабатывает случай сетчатки и может свободно использовать класс размера фона, поскольку сетчатка никогда не будет использоваться в 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;
         }
}

Пример использования:

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

Для этого у вас должно быть два файла:

  • start_grey-97_12.png
  • start_grey-97_12@2x.png

Где 2xфайл двойного разрешения для сетчатки.


8

Просто предоставьте всем изображения сетчатки и уменьшите изображение до половины его исходного размера внутри элемента изображения. Например, ваше изображение 400pxширокое и высокое - просто укажите ширину изображения, 200pxчтобы оно выглядело резким, как это:

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

Если ваше изображение является фотографическим, вы, вероятно, можете увеличить сжатие JPG на нем, не делая его хуже, потому что артефакты сжатия JPG, вероятно, не будут видны, когда изображение отображается по адресу 2x: см. Http://blog.netvlies.nl/ дизайн-взаимодействие / сетчатка-революция /


1
Даан Джобсис предполагает, что для фотографических изображений это даже не должно приводить к увеличению размера файла: см. Blog.netvlies.nl/design-interactie/retina-revolution
Paul D. Waite

В идеале вы должны указать высоту, чтобы браузер мог разместить страницу до того, как изображение будет загружено.
Пол Д. Уэйт,

8
Я не думаю, что это отличная идея - предоставить файл изображения большего размера и тяжелого размера, если в нем нет необходимости ...
jan267 06

1
@ PaulD.Waite интересно первым делом и точно напоследок! :)
jan267 06

2
@ PaulD.Waite Обратите внимание, что автор связанной статьи совершил несколько серьезных ошибок, которые обсуждаются здесь: silv.org/test/Retina-resize.html, поэтому к статье следует относиться с большой долей скептицизма . Особенно тот факт, что «немасштабированное изображение справа» на самом деле масштабировано и, таким образом, не может сравниваться с тем, разрешение которого точно удвоено (скажите своему браузеру, чтобы он отображал правильные изображения в новом окне, и вы увидите то, что я и автор той другой статьи имею ввиду)
Себастьян

1

если его фоновые изображения, простой способ сделать это:

    #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(image@2x.png); background-size: 50%; }
}

еще один простой способ - использовать этот метод:

Просто замените:

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

с участием

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

1

Я нашел этот интересный способ предоставления изображений с несколькими разрешениями.
На самом деле он использует CSS, чего я хотел избежать, и работает только в Safari и Chrome.
Я о чём image-set.

Вот пример , предоставленный Apple ( здесь ):

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

Я также хочу поделиться этими двумя ссылками:


1

С помощью JSF вы можете создать собственный тег Facelets, чтобы избавиться от ненужных добавлений srcsetк каждому изображению.

В вашем taglib.xmlможет быть что-то вроде:

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

И ваш тег может выглядеть примерно так:

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

Что можно использовать как:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:myTag="http://your.com/namespace-of-taglib">
  <myTag:src2x="image@2x.jpg"/>
</html>

И отобразит:

<img src="image.jpg"
     srcset="image@2x.jpg 2x"/>

0

Эта проблема особенно сложна с адаптивными сайтами, где и изображение может иметь разную ширину в зависимости от размера браузера. Также при работе с CMS, где несколько редакторов потенциально загружают тысячи изображений, мне казалось нереалистичным просить людей загружать специально сжатые изображения.

Итак, я написал сценарий, который учитывает это, он запускается внизу страницы и при завершении изменения размера. Каждый раз с учетом плотности пикселей и размера изображения.

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


0

Если вас не расстраивает боязнь использования java-скрипта, то вот хорошая статья http://www.highrobotics.com/articles/web/ready-for-retina.aspx . Имеет очень простое решение.

А пример на JSFiddle стоит тысячи слов.

С помощью:

<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');            
    });
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.