Как использовать атрибут srcset тега img: адаптивные изображения для чайников
37768 56 7
SEO
– Читать 17 минут
Прочитать позже
Максим Милютин
SEO-энтузиаст Miliutin.ru
Адаптивные изображения — стандарт для современных сайтов. Его поддерживают все браузеры, кроме Internet Explorer и Opera Mini, а Google прямо рекомендует использовать эту технологию. Но иногда у верстальщиков и SEO-специалистов возникают трудности с корректным внедрением атрибута srcset, что приводит, например, к неправильной индексации картинок поисковыми роботами.
В этой статье обсудим, как работают адаптивные изображения, почему браузер выбирает именно такую версию картинки, а не любую другую и как грамотно задать условия в sizes.
Содержание
В чем суть адаптивных изображений Почему картинки шириной 320px никому не нужны Как браузер обрабатывает тег img с атрибутом srcset
Как атрибут sizes позволяет контролировать работу браузера Как самостоятельно сформировать sizes Адаптивные иллюстрации и SEO
Индексация иллюстраций
Кол-во иллюстраций в srcset
Увеличение веса страницы
Адаптивные иллюстрации в AMP
Бонус. Lazy loading с помощью заглушек в srcset
В чем суть адаптивных изображений
Корги в большой опасности, судя по приближающемуся локомотиву
Мы сделали фотографию и хотим опубликовать ее в блоге. Фото шириной 5130px весит 3Мб. PageSpeed Insights отнимет у нас попугаев, если выложить его как есть.
Можно сократить ширину иллюстрации и опубликовать ее в уменьшенном виде. Но тогда наше фото как пользователи, так и поисковые роботы увидят в сжатом качестве.
Cделаем умнее: нарежем иллюстрацию на несколько копий и предложим браузеру выбрать нужную.
Теперь Chrome не будет загружать три мегабайта, когда пользователь заходит с iPhone SE с шириной экранчика 320px.
Многие статьи по адаптивным изображениям на SEO-ресурсах заканчиваются где-то на этом моменте. Кто-то еще про sizes коротко рассказывает, мол, разберетесь. Из-за этого ни оптимизаторы, ни верстальщики зачастую не понимают, что вообще у себя на сайте внедряют. Углубимся в теорию.
Почему картинки шириной 320px никому не нужны
Заходим на MyDevice.io. Сервис расскажет много интересного о наших устройствах: например, мой смартфон имеет ширину области просмотра (viewport width) 360px и соотношение пикселей (CSS pixel-ratio) 3.
Если я открою сайт, где картинка растянута на всю ширину (100% viewport), то она займет 360 CSS-пикселей (тех, с которыми оперируют верстальщики). Но разрешение моего экрана не 360 каких-то там абстрактных пикселей, а 1080 реальных!
В этом весь фокус. Число физических (реальных) пикселей равно числу CSS-пикселей, умноженному на соотношение пикселей (pixel ratio).
Век экранов, у которых число реальных и CSS-пикселей совпадает, давно кончился. Помните, когда-то Apple революционно вышла на рынок с ретина-дисплеями? Это когда pixel ratio — 2. На Samsung Galaxy S6 2015 года соотношение физических пикселей к CSS-пикселям 4! Большинство китайских смартфонов сегодня — это pixel ratio 2-3.
А значит, если у нас на мобилке картинка занимает 360px, нет смысла загружать иллюстрацию шириной меньше, чем 360×2=720px! А обладатель корейского флагмана был бы не против и все 1440px загрузить.
Запомнить: когда рассчитываем необходимое качество изображения, надо учитывать соотношение пикселей девайса.
Как браузер обрабатывает тег img с атрибутом srcset
В общих словах алгоритм такой: сначала браузер определяет ширину иллюстрации, которую та занимает в верстке (CSS-пиксели). Затем умножает это значение на pixel ratio устройства и получает реальную ширину — ровно такую картинку надо загрузить на устройство, чтобы пользователь увидел изображение в максимальном качестве.
Далее браузер идет в массив srcset, где ищет подходящую картинку. Например, идеальной была бы ширина 1032px, но есть только 1200px и 960px. Браузер возьмет 1200px, так как это подходящее значение (обычно браузер берет первое изображение, которое больше размера выбранного слота).
На демо-странице #1 вы можете потестировать, как браузер выбирает иллюстрацию при изменении pixel ratio устройства. Ширина картинки равна 360px и не зависит от device-width.
Основная иллюстрация ушла в src, в srcset я указал копии шириной 360px, 720px, 1080px, 1920px. На атрибут sizes пока не обращайте внимания.
Отмечу, что вместо px в srcset используется w — дескриптор ширины. Это очень удобно, если запомнить, что w — это реальные пиксели, а px — CSS-пиксели, и тогда работа srcset/sizes станет еще понятнее.
Вместо дескриптора ширины (w) может использоваться дескриптор плотности пикселей (x), когда мы говорим браузеру, что вот эта картинка для обычных устройств, а эта — для ретина-дисплеев. Но встречаю я такое редко, так что вернемся к нашей иллюстрации на демо-странице.
Тестировать работу адаптивных изображений очень удобно с помощью инструментов разработчика Google Chrome.
Нажмите F12, перейдите во вкладку Network.
Выберите фильтр Img. Так мы будем видеть все иллюстрации, которые загружает браузер вместе со страницей.
В левом верхнем краю панели разработчика — иконка со смартфоном. С помощью этой функции мы можем смотреть на сайт с экрана смартфона, планшета и вообще любого устройства.
Слева вверху появляется панель настройки девайса. Из выпадающего списка можно выбрать конкретное устройство, но мы сами зададим параметры экрана, поэтому выбираем Responsive. Указываем ширину 360, высоту 640. Справа будет параметр DPR — это как раз device pixel ratio.
Если вдруг параметр не отображается, нажмите на три точки еще правее и выберите Add device pixel ratio.
Выберите DPR = 1.0 и перезагрузите страницу (Ctrl+Shift+R). В табличке справа увидите название иллюстрации, которую загрузил браузер. Затем повторите эксперимент с DPR 2.0 и 3.0. Браузер последовательно загрузит картинки шириной 360, 720 и 1080 пикселей.
Затем задайте ширину и высоту девайса 1920x1080px. При DPR 3.0 по-прежнему загружается dog-1080.jpg.
А теперь перейдите на демо-страницу #2. На ней все то же самое, однако в теге img нет атрибута sizes. Для смартфона с device-width 360px и DRP 3.0 по-прежнему загружается иллюстрация на 1080px, однако для десктопа 1920x1080px — уже, почему-то, версия на 1920px.
Картинка по-прежнему занимает 360 CSS-пикселей, device pixel ratio по-прежнему 3, однако браузер почему-то грузит слишком большую картинку. Причина — в отсутствии атрибута sizes. Если он не заполнен, то по умолчанию используется значение 100vw.
То есть браузер считает, что такая картинка занимает 100% device width.
Так как мы загружаем страницу с шириной экрана 1920px, браузер полагает, что и картинка с песиком занимает 1920px в ширину, а значит, надо скачивать самую большую иллюстрацию из массива srcset.
Запомнить: без атрибута sizes браузер подберет картинки из srcset некорректно.
Как атрибут sizes позволяет контролировать работу браузера
При первичной калькуляции браузер не знает ширину изображения в верстке страницы. Чтобы понять размер картинки в CSS-пикселях, браузер изучает значение атрибута sizes.
Теперь мы можем полностью описать алгоритм работы с отзывчивыми изображениями:
Браузер дошел до тега <img>. Он знает только device-width и pixel ratio — это исходные параметры устройства.
Браузер считывает условия в атрибуте sizes, сверяя их со значением device-width. Делает он так до первого истинного условия.
Зная ширину картинки в CSS-пикселях (из sizes) и pixel ratio, браузер высчитывает необходимую ширину иллюстрации в реальных пикселях.
Браузер идет в srcset и из массива изображений подбирает подходящее по ширине.
Задача верстальщика — с помощью медиа-запросов корректно описать размер иллюстрации в CSS-пикселях в разных состояниях верстки. Если на десктопе картинка занимает 560px, а на мобилке 100% ширины экрана, то ровно это и надо рассказать браузеру с помощью sizes.
sizes="(max-width: 560px) 100vw, 560px"
В примере браузер считает такую информацию: если device-width меньше или равен 560px, то картинка занимает 100% viewport, иначе — 560px. Когда пользователь зайдет на страницу с iPhone 8, то условие будет истинно и браузер поймет, что иллюстрация занимает 375 css-пикселей. А если человек загружает страницу с десктопа, то условие будет ложным, и браузер выберет второе значение — 560px.
Кстати, обратите внимание, что max-width — это именно меньше или равно.Некоторые верстальщики из-за этого совершают ошибку, когда описывают в sizes якорные значения, при которых состояние картинки уже изменилось.
В большинстве случаев достаточно последовательного использования max-width, но можно конструировать условия любой сложности.
При этом описывать состояние картинки при текущем медиа-запросе можно как с помощью CSS-пикселей (px), так и с помощью vw — доли области просмотра в %.
sizes="((min-width: 600px) and (max-width: 1004px)) 84vw, (min-width: 1005px) 60vw, 100vw"
Пример с NYTimes. Если device-width от 600px до 1004px включительно (планшет), то иллюстрация занимает 84%, если больше 1005px включительно (десктоп), то 60%, в иных случаях (смартфоны) — 100% viewport.
В качестве значения при медиа-запросе можно использовать и более сложные материи, например calc. Ниже пример sizes с одного из сайтов. В нем полностью описывается состояние иллюстрации при изменении device-width: например, если ширина экрана 1024px, то иллюстрация занимает (100% viewport — 504px) = 520px. Для этого используется calc.
Деталь: в sizes можно одновременно использовать и vw, и px, тогда как в srcset используется дескриптор либо ширины (w), либо плотности (x).
Строго говоря, степень детализации sizes зависит только от дотошности верстальщика — если у вас создается всего две копии изображения шириной 640px и 1200px, то проще будет в sizes описать не реальные состояния верстки, а условия, при которых мы приказываем браузеру брать либо первое фото, либо второе.
Запомнить: с помощью sizes мы управляем браузером, указывая ему какую иллюстрацию подгружать в каком случае.
Как самостоятельно сформировать sizes
Прежде всего, попросите этим заняться верстальщика. Ситуация, при которой SEO-специалист описывает медиа-запросы, — скорее вынужденная, html-кодом должны заниматься профессионалы.
Но если по-другому никак, то вооружайтесь Chrome DevTools и скромными математическими познаниями — большего не понадобится. Для примера я вместе с вами сформирую sizes для популярного российского новостного сайта.
Наша задача — описать состояния основной иллюстрации в зависимости от ширины экрана пользователя. Сколько картинка занимает в верстке, если человек заходит с телефона? А если с планшета? И так далее.
Заходим в DevTools и выставляем начальное значение девайса: Responsive, 320px. Кликаем правой клавишей по иллюстрации, которая нас интересует, и выбираем пункт «Просмотреть код». В панели разработчика появится html-код, центрированный на нашем изображении. Наводим курсор на <img>, после чего браузер подсветит текущие размеры иллюстрации.
При ширине экрана 320px иллюстрация занимает 280px. Записываем и идем дальше, возьмем 360px. Теперь картинка занимает 320px. Чувствуете зависимость? По бокам от картинки — белые поля шириной 20px каждое, так что описать состояние иллюстрации можно формулой: calc (100vw — 40px).
Но как долго действует эта зависимость? Проще всего это выяснить, растягивая ширину нашего виртуального девайса. Выясняется, что где-то в районе 536px поля вокруг картинки увеличиваются. Находим точное значение — это 540px. При ширине девайса 541px, картинка по-прежнему занимает 500px, а не 501px, как мы планировали.
Наш первый медиазапрос готов:
(max-width: 540px) calc(100vw - 40px)
Что переводится как «при ширине экрана меньше или равной 540px, картинка занимает 100% ширины экрана минус 40px».
Далее видим, что с 540px до 640px размер иллюстрации не меняется, увеличиваются только боковые поля. Это наше следующее условие:
(max-width: 640px) 500px
Это самый простой способ формировать sizes: так как браузер последовательно проверяет все условия, мы выстраиваем медиа-запросы «лесенкой», плавно поднимая max-width вверх.
При device-width 641px, картинка занимает 590px и в таком состоянии находится во всех остальных случаях. То есть даже появление левой и правой боковых колонок никак на ситуацию не влияют, можно сказать, что нам повезло.
Если ширина экрана устройства меньше или равна 540px, то вычти из нее 40px и получишь размер картинки в css-пикселях, иначе проверяй условие #2.
Если ширина экрана устройства меньше или равна 640px, то картинка занимает 500 css-пикселей, во всех остальных случаях — 590 css-пикселей.
Адаптивные иллюстрации и SEO
Индексация иллюстраций
С точки зрения поисковой оптимизации важно, чтобы в src была указана ссылка на изображение в максимальном качестве. Именно оно будет индексироваться поисковыми роботами. Таким образом можно получить преимущество над конкурентами, которые до сих пор ищут компромисс между качеством и скоростью загрузки.
Для примера обратимся к новостному сайту, на котором реализованы адаптивные иллюстрации. В src уходит картинка размером 1600x900px, в srcset, помимо прочего, указана ее копия 921x518px.
Теперь идем в Google и смотрим, какую версию проиндексировал робот. Оказывается — оригинальную.
Кол-во иллюстраций в srcset
Также разработчики зададут вопрос: сколько версий иллюстрации создавать для srcset?
Если верстаете что-то трудозатратное, например, лендинг или ключевую страницу вашего сайта, то стоит заморочиться максимально. Изучите все состояния картинки в верстке и сопоставьте эти данные с аудиторией сайта.
Например, в Яндекс.Метрике можно выяснить, что 41% визитов на сайт происходит с девайсов шириной 360 CSS-пикселей. Обычно это всякие Samsung.
Если на этом разрешении иллюстрация занимает 100vw, то есть 360px, то нам надо предусмотреть как минимум две копии иллюстрации: 720px и 1080px. 1440px тоже было бы неплохо, ведь именно на Samsung чаще всего встречаешь соотношение пикселей в 4.
Если подробно изучать аудиторию нет времени, воспользуйтесь стандартными пропорциями, которые рекомендовал в докладе об изображениях Demi Murych:
640px.
920px.
1220px.
1920px уходит в src.
Увеличение веса страницы
Внедрение адаптивных изображений может увеличить объем загружаемых данных. Например, если раньше все пользователи сайта грузили одну-единственную картинку шириной 945px, то после внедрения отзывчивости владелец Samsung Galaxy S8 будет скачивать что-то в районе 360 × 4 = 1440px.
Чтобы прощупать самостоятельно, поиграйтесь с тестовой страницей #4. Там две картинки: первая шириной 945px, вторая — с несколькими копиями в srcset.
Если пользователь заходит с дешевого китайского смартфона (360px device-width, pixel ratio 2), то загрузится версия на 640px. В нашем случае 277 килобайтов против 498 — экономия 44%.
А вот если пользователь заходит с iPhone X (375px device-width, pixel ratio 3), то загрузится уже версия на 1200px. В нашем случае это на 265кб больше, то есть прирост объема на 53%.
Картинки в примере не оптимизированы, поэтому цифры такие большие. Но логика должна быть понятна: если у вас статья с десятью картинками, то пользователи с хорошими смартфонами будут скачивать очень много качественных иллюстраций, это надо учитывать при внедрении адаптивных иллюстраций на свой сайт.
Например, у нас есть статья с основной картинкой, которую пользователь загружает на первом экране. Для улучшения LCP нам выгодно, чтобы эта иллюстрация отрисовывалась как можно быстрее. Поэтому для нее мы прописываем srcset, в котором максимальное качество — x2. А остальные иллюстрации в статье — вплоть до x4, если так нужно.
Адаптивные иллюстрации в AMP
Не забудьте распространить адаптивные иллюстрации и на AMP-страницы, если аудитория вашего сайта ими пользуется. Подробнее — в статье на Amp.dev.
Бонус. Lazy loading с помощью заглушек в srcset
На srcset основана особая технология ленивой загрузки, которую проповедует уже упомянутый ранее Demi Murych. Если кратко: делаем всё, что было описано в этой статье, но только в srcset используем не реальные копии иллюстрации, а сверхлегкую заглушку. И только когда картинка подкрадывается к области просмотра пользователя, мы подменяем массив изображений в srcset на реальный с помощью скрипта.
Таким образом браузер загружает суперлегкую заглушку для иллюстраций, не попавших в поле зрения пользователя. Это позволяет ликвидировать недостаток адаптивных иллюстраций, связанный с увеличением общего объема картинок для пользователей с хорошими смартфонами.
И никаких проблем с индексацией: поисковый робот в srcset не заглядывает, используя лишь изображение максимального качества в src. Если заинтересовались, изучите соответствующее видео.
Полезные источники: MDN, Google Developers, WHATWG, Web.Dev.
Чтобы быть в курсе всех новостей блога Serpstat, подписывайтесь рассылку. А также вступайте в чат любителей Серпстатить и подписывайтесь нанаш канал в Telegram.
Serpstat — набор инструментов для поискового маркетинга!
Находите ключевые фразы и площадки для обратных ссылок, анализируйте SEO-стратегии конкурентов, ежедневно отслеживайте позиции в выдаче, исправляйте SEO-ошибки и управляйте SEO-командами.
Набор инструментов для экономии времени на выполнение SEO-задач.
Получить бесплатный доступ на 7 дней
Мнение авторов гостевого поста может не совпадать с позицией редакции и специалистов компании Serpstat.
Оцените статью по 5-бальной шкале
4.74 из 5 на основе 86 оценок
Нашли ошибку? Выделите её и нажмите Ctrl + Enter, чтобы сообщить нам.
Рекомендуемые статьи
SEO +1
Андрей
Как использовать Google Trends для анализа ключевых фраз
SEO +1
Maksym Astakhov
Как проверить позиции сайта за любой период: фишки мониторинга позиций.
SEO +1
Анастасия Сотула
Как эффективно управлять SEO-командой: опыт HubSpot, Netpeak, Citrus и не только
Кейсы, лайфхаки, исследования и полезные статьи
Не успеваешь следить за новостями? Не беда! Наш любимый редактор подберет материалы, которые точно помогут в работе. Только полезные статьи, реальные кейсы и новости Serpstat раз в неделю. Присоединяйся к уютному комьюнити 🙂
Нажимая кнопку, ты соглашаешься с нашей политикой конфиденциальности.
Поделитесь статьей с вашими друзьями
Вы уверены?
Спасибо, мы сохранили ваши новые настройки рассылок.
Сообщить об ошибке
Отменить
Уникализация фото для Авито онлайн: сервис размножения картинок ImgFactory
ImgFactory.ru позволяет делать неограниченное количество
копий изображений с небольшими изменениями в 1 клик в соответствии с заданными настройками. Рандомизация осуществляется по ряду параметров, которые несущественно меняют изображение.
При этом выходные файлы определяются как уникальные для любых досок объявлений (Авито, Юла)
и прочих сервисов, которые требуют индивидуальные изображения.
Внимание: Поисковые системы умеют хорошо распознавать
изображения, поэтому не рекомендуем использовать наш сервис для создания уникальных картинок
для сайтов!
Начать работу
Возможности сервиса
Изменение качества
Изменение размера
Изменение яркости
Изменения контраста
Поворот изображения
Обрезка изображения
Сохранение копий
И всё это со случайными значениями изменений!
Поможем сделать картинку уникальной для Авито онлайн
Наш сервис решает проблему быстрой пакетной уникализации изображений для доски объявлений Авито. Есть несколько вариантов размножения. Можно просто уникализировать выборку фотографий или же подобрать картинки к одному товару. Также результат работы можно использовать на других досках, таких как Юла и OLX.
Создание уникальных изображений для инстаграм массово
Для создания и продвижения своих аккаунтов в инстаграм, вам понадобятся уникальные фото. Теперь достаточно сделать подборку изображений, загрузить ее к нам и наша программа сделает всю работу за вас всего за несколько минут. Экономьте свое время вместе с нами!
Примеры уникализированных изображений
Исходное изображение
Поворот
Обрезка
Изменение размера
Контраст
Преимущества регистрации
Гость
Доступны базовые функции сервиса, с ограничением — вам доступно 10 лимитов в день
Пользователь
Все функции сервиса доступны без ограничений, за каждую копию
изображения расходуются лимиты
Эрик работает евангелистом в Cloudinary и живет на прекрасном острове Оркас. Он любит визуальную коммуникацию, обучение через преподавание и строительство, а также…
Больше о
Эрик ↬
Несколько дней назад мы опубликовали статью о Picturefill 2.0, идеальном полифилле для адаптивных изображений. Сегодняшняя статья дополняет статью Тима Райта и объясняет, как именно мы можем использовать грядущие 9 лет.0014 Элемент и srcset с простыми запасными вариантами для устаревших браузеров. [Нет причин ждать адаптивных изображений; на самом деле мы можем получить их очень скоро.
Изображения являются одними из самых важных частей информации в Интернете, но за 25-летнюю историю Интернета они вообще не были очень адаптируемыми. Все в них было упрямо исправлено: их размер, формат и обрезка, все высечено в камне одним src .
«Все, что я сказал до сих пор, можно резюмировать следующим образом: создавайте адаптируемые страницы… Разработка адаптируемых страниц — это разработка доступных страниц. трудности, к информации».
— Джон Оллсопп, Дао веб-дизайна
Авторы HTML начали по-настоящему ощущать эти ограничения, когда экраны с высоким разрешением и адаптивные макеты поразили сеть, как раз-два удара. Авторы, желая, чтобы их изображения выглядели четкими в огромных макетах и на экранах с высоким разрешением, начали рассылать всем источники все большего и большего размера; средний размер файла изображения увеличился; очень умные люди назвали адаптивный веб-дизайн «невероятно медленным».
Изображения были препятствием номер один к реализации действительно адаптируемых и производительных адаптивных страниц — страниц, которые масштабируются как вверх, так и вниз, эффективно адаптируясь как к ограничениям, так и к возможностям текущего контекста просмотра.
Это скоро изменится.
Последняя спецификация элемента является результатом многолетних споров о том, как сделать так, чтобы изображения адаптировались. Это дает авторам семантические способы группировать несколько версий одного и того же изображения, причем каждая версия имеет технические характеристики, которые делают ее более или менее подходящей для конкретного пользователя. Новая спецификация достигла широкого консенсуса и внедряется в Chrome, Opera, Firefox и Edge (ссылка) по мере того, как я печатаю.
Самое время начать изучать этот материал сейчас !
Больше после прыжка! Продолжить чтение ниже ↓
Прежде чем мы перейдем к какой-либо разметке ( блестящий! новый! ), давайте рассмотрим соответствующие способы изменения среды просмотра, то есть способы, которыми мы хотим, чтобы наши изображения адаптировались.
Наши изображения должны быть в состоянии четко отображать различных устройств-пикселей с. Мы хотим, чтобы экраны с высоким разрешением получали изображения с высоким разрешением, но мы не хотим отправлять эти изображения пользователям, которые не увидят все эти лишние пиксели. Назовем это 9Вариант использования 0014 device-pixel-ratio .
Если наш макет гибкий (т. е. адаптивный), то наши изображения должны будут сжаться и растянуться, чтобы соответствовать ему. Мы назовем этот вариант использования плавного изображения.
Обратите внимание, что эти два варианта использования тесно связаны: для решения обоих нам нужно, чтобы наши изображения были доступны в нескольких разрешениях, чтобы они эффективно масштабировались. Мы будем называть решение обеих проблем одновременно вариантом использования изображения переменного размера
Иногда нам нужно адаптировать наши изображения способами, выходящим за рамки простого масштабирования. Мы можем захотеть обрезать изображения или даже слегка изменить их содержимое. Мы назовем это вариантом использования арт-директора.
Наконец, разные браузеры поддерживают разные форматы изображений. Мы могли бы захотеть отправить модный новый формат, такой как WebP, в браузеры, которые могут его отображать, и вернуться к проверенным старым JPEG в браузерах, которые этого не делают. Мы назовем это вариантом использования с переключением типов.
Новая спецификация включает функции для всех этих случаев. Давайте посмотрим на них один за другим.
Переупорядочивать изображения для разных разрешений относительно легко, однако загружать разные изображения (и только их) в зависимости от разрешения пользователя довольно сложно. Ну, не больше. (Изображение предоставлено) Отношение устройств к пикселям Пример использования
Начнем просто с изображения фиксированной ширины, которое мы хотим адаптировать к различным отношениям устройств к пикселям с. Для этого воспользуемся первым инструментом, который дает нам новая спецификация для группировки и описания источников изображений: атрибутом srcset .
Допустим, у нас есть две версии изображения:
small.jpg (320 × 240 пикселей)
large.jpg (640 × 480 пикселей)
Мы хотим отправить large.jpg только пользователям с экранами высокого разрешения. Используя srcset , мы разметили бы наше изображение следующим образом:
Атрибут srcset принимает список URL-адресов изображений, разделенных запятыми, каждый с дескриптором x , указывающим соотношение пикселей устройства , для которого предназначен этот файл.
src предназначен для браузеров, которые не понимают источник . alt , конечно же, включен для браузеров, которые вообще не отображают изображения. Один элемент и три атрибута дают нам изображение, которое выглядит четким на устройствах с высоким разрешением и эффективно ухудшается вплоть до текста. Не слишком потертый!
Примеры использования гибких изображений и изображений переменного размера
Чего эта разметка не сделает, так это эффективно сожмет и растянет наше изображение в гибком макете. Прежде чем перейти к этому варианту использования изменчивого изображения, нам нужно немного узнать о том, как работают браузеры.
Предварительная загрузка изображений, по словам Стива Содерса, «самое большое улучшение производительности, которое когда-либо делали браузеры». Изображения часто являются самыми тяжелыми элементами на странице; загрузка их как можно скорее отвечает интересам каждого. Таким образом, первое, что браузер сделает со страницей, — просканирует HTML в поисках URL-адресов изображений и начнет их загрузку. Браузер делает это задолго до того, как сконструирует DOM, загрузит внешний CSS или нарисует макет. Таким образом, решить вариант использования плавного изображения сложно; нам нужно, чтобы браузер выбрал источник, прежде чем он узнает размер отображаемого изображения.
То, что браузер всегда знает, — это среда, которую он отображает в : размер области просмотра, разрешение экрана пользователя и тому подобное. Мы используем эту информацию, когда используем медиа-запросы, которые адаптируют наши макеты к конкретным средам просмотра.
Таким образом, чтобы обойти проблему с предварительной загрузкой, в первых предложениях по функциям гибкого изображения предлагалось присоединять медиа-запросы к источникам. Мы бы основывали наш механизм выбора источника на размере окна просмотра, который браузер знает во время выбора, а не на окончательном отрендеренном размере изображения, которого он не знает.
Работа с адаптивными изображениями оказалась настоящим кошмаром. Лучший способ предоставить браузеру сведения о его окружении — просто сообщить браузеру отображаемый размер изображения. Вроде очевидно, правда. (Изображение предоставлено)
Как оказалось, это плохая идея. Хотя это технически выполнимо, вычисление необходимых медиа-запросов утомительно и подвержено ошибкам. Лучше всего указать просто сообщить браузеру отображаемый размер изображения !
Как только мы сообщаем браузеру, сколько пикселей требуется (с помощью нового атрибута, размеров ) и сколько пикселей имеет каждый из источников (через дескрипторы w в srcset ), выбор источника становится тривиальным. Браузер выбирает наименьший источник, который все еще будет выглядеть достаточно четким в своем контейнере.
Давайте сделаем это конкретным, развивая наш предыдущий пример. Предположим, теперь у нас есть три версии нашего изображения:
large.jpg (1024 × 768 пикселей)
medium.jpg (640 × 480 пикселей)
small.jpg (320 × 240 пикселей)
И мы хотим поместить их в гибкую сетку — сетку, которая начинается как один столбец, но переключается до трех столбцов в больших окнах просмотра, например:
Пример адаптивной сетки. (см. демонстрацию)
Вот как мы его разметим:
Мы снова используем srcset , но вместо дескрипторов x мы присоединяем к нашим источникам дескрипторы w . Они описывают фактическую ширину в пикселях файла, на который делается ссылка. Итак, если вы «Сохранить для Интернета…» с разрешением 1024 × 768 пикселей, то разметьте этот источник в srcset как 1024w .
Обратите внимание, что мы указываем только ширину изображения . А почему не высоты? Изображения в нашем макете ограничены по ширине; их ширина явно задается CSS, а высота — нет. Подавляющее большинство адаптивных изображений в дикой природе также ограничены по ширине, поэтому спецификация упрощает работу, имея дело только с шириной. Есть несколько веских причин для включения высоты, но не сейчас.
Итак, это w в srcset , который описывает, сколько пикселей имеет каждый из наших источников . Далее, атрибут размеров . Атрибут размеров сообщает браузеру, сколько пикселей ему нужно , описывая окончательную визуализируемую ширину нашего изображения. Думайте о размерах как о способе немного заблаговременно дать браузеру немного информации о макете страницы, чтобы он мог выбрать источник до того, как он проанализирует или отобразит какой-либо CSS страницы.
Мы делаем это, передавая браузеру длину CSS, которая описывает визуализируемую ширину изображения. Длина CSS может быть абсолютной (например, 99px или 16em ) или относительно области просмотра ( 33.3vw , как в нашем примере). Эта часть «относительно области просмотра» позволяет изображениям изгибаться.
Если наше изображение занимает треть области просмотра, то наш атрибут размеров должен выглядеть так:
размеры="33.3vw"
Наш пример не так прост. Наш макет имеет точку останова на 36 ems. Когда окно просмотра уже, чем 36 ems, макет меняется. Ниже этой точки останова изображение будет занимать 100% ширины области просмотра. Как мы закодируем эту информацию в нашем размеры атрибут?
Мы делаем это, соединяя медиазапросы с длинами:
размеры="(мин-ширина: 36em) 33.3vw,
100vw"
Это его формат:
размеры="[медиа-запрос] [длина],
[медиа-запрос] [длина],
и т. д…
[длина по умолчанию]"
Браузер просматривает каждый медиа-запрос, пока не найдет подходящий, а затем использует длину парного запроса. Если нет совпадений медиа-запросов, браузер использует длину «по умолчанию», т. е. любую длину, с которой он сталкивается, не имеющую парного запроса.
Имея на выбор размеров длины и набор источников с w дескрипторами в srcset , у браузера есть все необходимое для эффективной загрузки изображения в гибком, отзывчивом макете.
Замечательно, размеров и w в srcset также дают браузеру достаточно информации, чтобы адаптировать изображение к различным соотношениям пикселей устройства s. Преобразовав длину CSS, мы даем размеров в пиксели CSS; и, умножив это на 9 пользователей0014 device-pixel-ratio , браузер знает количество пикселей устройства, которое ему необходимо заполнить — независимо от того, какое у пользователя значение device-pixel-ratio .
Таким образом, в то время как пример в нашем сценарии использования device-pixel-ratio работает только для изображений с фиксированной шириной и охватывает только экраны 1x и 2x, этот пример srcset и размеров охватывает не только использование гибких изображений. случае, но и адаптируется к произвольной плотности экрана.
Мы решили обе проблемы сразу. Говоря языком, изложенным в начале этой статьи, w в srcset и размеры охватывают вариант использования изображения переменного размера.
Что еще более удивительно, эта разметка также дает браузеру некоторое пространство для маневра . Прикрепление определенных условий просмотра к источникам означает, что браузер делает выбор на основе строгого набора условий. «Если экран высокого разрешения, — говорим мы браузеру, — то вы должны использовать этот источник». Просто описав размеры ресурсов с помощью w в srcset и область, которую они будут занимать с размерами , мы позволяем браузеру применять свои дополнительные знания о среде данного пользователя для решения проблемы выбора источника. Спецификация позволяет браузерам, скажем, опционально загружать источники меньшего размера, когда полоса пропускания медленная или дорогая.
Еще кое-что. В нашем примере размер изображения всегда представляет собой простой процент от ширины области просмотра. Что, если бы наш макет объединил как абсолютную, так и относительную длину, скажем, добавив фиксированную боковую панель размером 12 em к макету из трех столбцов, как здесь?
Макет сочетает в себе абсолютную и относительную длину. (См. демонстрацию)
Мы использовали бы удивительно хорошо поддерживаемую функцию calc() в нашем атрибуте размеров .
Теперь мы готовим на газу! Мы научились размечать изображения переменного размера, которые эффективно увеличиваются и уменьшаются, обеспечивая четкое отображение на любых макетах, окнах просмотра и экранах.
Но что, если мы хотим пойти дальше? Что, если бы мы хотели адаптироваться больше?
Когда в прошлом году Apple представила iPad Air, на ее веб-сайте было размещено огромное изображение устройства. Это может показаться довольно непримечательным, если только вы — как обычно делают гики веб-дизайна — навязчиво не изменили размер окна браузера. Когда область просмотра была достаточно короткой, iPad делал замечательную вещь: он поворачивался, чтобы лучше соответствовать области просмотра!
Мы называем такие вещи «художественным направлением».
Apple управляла своим изображением, злоупотребляя HTML и CSS: размечая свое изображение — которое явно содержало — как пустую div и переключение его background-image с помощью CSS. Новая спецификация позволяет авторам делать такое художественное направление на основе точек останова полностью в HTML.
Спецификация облегчает это, накладывая другой метод группировки источников поверх srcset : и source .
Вернемся к нашему примеру. Предположим, что вместо того, чтобы позволить нашему изображению заполнять всю ширину области просмотра на маленьких экранах, мы обрезаем квадрат изображения, увеличивая наиболее важную часть объекта, и представляем этот маленький квадрат фиксированного размера, смещенный влево. , оставив много места для описательного текста, например:
Пример с изображениями в сочетании с описательным текстом. (см. демонстрацию)
Для этого нам потребуется несколько дополнительных источников изображений:
croped-small.jpg (96 × 96 пикселей)
croped-large.jpg (192 × 192) пикселей)
small.jpg (320 × 240 пикселей)
medium.jpg (640 × 480 пикселей)
large.jpg (1024 × 768 пикселей) 910094 9000 ? Вот так:
<картинка>
картинка>
Этот пример настолько сложен, насколько это возможно, в нем используются все функции, которые мы рассмотрели до сих пор. Давайте сломаем это.
Элемент содержит два источник s и img . Исходники представляют собой две отдельные художественные версии изображения (квадратная обрезка и полная обрезка). (Обязательно) img служит нашим запасным вариантом. Как мы скоро обнаружим, большую часть фактической работы он выполняет за кулисами.
Во-первых, давайте внимательно посмотрим на этот первый источник :
Этот источник представляет полную необрезанную версию нашего изображения. Мы хотим показывать полное изображение только в трехколоночной раскладке — то есть, когда окно просмотра шире 36 ems. Первый атрибут здесь, media=“(min-width: 36em)” , делает это возможным. Если запрос в атрибуте media оценивается как true , тогда браузер должен использовать этот источник ; в противном случае оно пропускается.
Два других атрибута источника — srcset и размеры — в основном скопированы из нашего предыдущего примера с изображением переменного размера. Одно отличие: поскольку этот источник будет выбран только для макета с тремя столбцами, нашему атрибуту размеров нужна только одна длина, 33.3vw .
Когда область просмотра уже 36 ems, медиа-запрос первого источника будет оцениваться как false , и мы перейдем ко второму:
Представляет наш небольшой квадратный урожай. Эта версия отображается с фиксированной шириной, но мы по-прежнему хотим, чтобы она отображалась четко на экранах с высоким разрешением. Таким образом, мы предоставили версии 1x и 2x и разметили их простыми дескрипторами x .
Наконец, мы подошли к удивительно важному ( действительно требуется! ) img .
Любой дочерний элемент audio или video , который не является источником , рассматривается как запасной контент и скрывается в поддерживающих браузерах. Следовательно, вы могли бы предположить то же самое о изображение здесь. Неправильный! Пользователи на самом деле видят элемент img , когда мы используем . Без img изображения нет; и все его source просто существуют, чтобы кормить его источником.
Почему? Одна из основных жалоб на первую спецификацию заключалась в том, что она заново изобрела колесо, предложив совершенно новый мультимедийный элемент HTML, аналогичный аудио и видео 9.0015 , который в основном дублировал функциональность img . Дублированная функциональность означает дублирование работы по внедрению и обслуживанию — работу, которую производители браузеров не стремились выполнять.
Таким образом, повторное использование новой спецификации img . Сам невидим, немного похож на волшебный span . Его исходные s предназначены только для того, чтобы браузер мог рисовать альтернативные версии изображения. Как только исходный URL-адрес выбран, этот URL-адрес передается в изображение . На практике это означает, что любые стили, которые вы хотите применить к визуализированному изображению (например, max-width: 100% ), должны применяться к img , а не к .
Итак, переходим к нашей последней функции.
Вариант использования с переключением типов
Предположим, что вместо того, чтобы делать все это сжатие, растяжение и адаптацию к бесчисленным условиям области просмотра, мы просто хотим попробовать новый формат файла и предоставить запасной вариант для неподдерживающих браузеров. . Для этого мы следуем схеме, установленной аудио и видео : тип источника .
<картинка>
png" />
картинка>
Если браузер не понимает тип мультимедиа image/svg , он пропускает первый источник ; если он не может сделать орёл или решка image/png , то он возвращается к img и GIF.
Во время чрезвычайно болезненного периода перехода от GIF к PNG веб-дизайнеры убили бы за такую возможность. Элемент дает нам это, готовя почву для легкого внедрения новых форматов изображений в ближайшие годы.
Вот и все!
Вот и все: каждая функция в новой спецификации и ее обоснование. Всего srcset , x , w , размеры , , source , media и type дают нам богатый набор инструментов, с помощью которых можно сделать изображения действительно адаптируемыми — изображения, которые могут ( наконец! ) эффективно перемещаться в гибких макетах и широкий выбор устройств.
Спецификация еще не окончательная . Первые реализации находятся в стадии разработки и проводятся под экспериментальными флагами; его разработчики и авторы ежедневно работают вместе над уточнением деталей спецификации. Все это происходит под эгидой группы сообщества Responsive Images. Если вы хотите продолжить, присоединяйтесь к группе, загляните на канал IRC, оцените проблему GitHub или отправьте новую, подпишитесь на информационный бюллетень или подпишитесь на RICG в Twitter.
Дополнительная литература на SmashingMag:
Выбор решения для адаптивных изображений
Одно решение для адаптивных изображений
Адаптивные изображения в WordPress с художественным оформлением
Модели распространения в изображение Imagen: Модели распространения текста в изображение
беспрецедентный фотореализм × глубокий уровень понимания языка
беспрецедентный фотореализм
глубокий уровень понимания языка
Исследование Google, команда Brain Team
Мы представляем Imagen, модель распространения текста в изображение с беспрецедентной степенью фотореализма и глубоким уровнем понимания языка. Imagen опирается на мощь больших языковых моделей преобразования в понимании текста и опирается на силу моделей диффузии в высокоточном создании изображений.
Наше ключевое открытие состоит в том, что универсальные большие языковые модели (например, T5), предварительно обученные на текстовых корпусах, удивительно эффективны.
эффективен при кодировании текста для синтеза изображений: увеличение размера языковой модели в Imagen повышает как точность выборки, так и текст изображения
выравнивание гораздо больше, чем увеличение размера модели рассеяния изображения.
Imagen достигает нового современного балла FID 7,27 в наборе данных COCO, даже не обучаясь на COCO, и люди-оценщики считают, что образцы Imagen находятся на одном уровне с самими данными COCO в выравнивании изображения и текста.
Для более глубокой оценки моделей преобразования текста в изображение мы представляем DrawBench, всеобъемлющий и сложный эталонный тест для моделей преобразования текста в изображение. С помощью DrawBench мы сравниваем Imagen с последними методами, включая VQ-GAN+CLIP, модели скрытой диффузии и DALL-E 2, и обнаруживаем, что оценщики-люди предпочитают Imagen другим моделям в параллельных сравнениях, как с точки зрения качества выборки и выравнивание изображения и текста.
Еще от семьи Imagen:
Мозг едет на ракетном корабле, направляющемся к Луне. Мозг едет на ракетном корабле, направляющемся к Луне. Драконий фрукт в поясе для карате в снегу. Драконий фрукт в поясе для карате в снегу. Маленький кактус в соломенной шляпе и неоновых солнцезащитных очках в пустыне Сахара. Маленький кактус в соломенной шляпе и неоновых солнцезащитных очках в пустыне Сахара. Фотография собаки корги на велосипеде на Таймс-сквер. На нем солнцезащитные очки и пляжная шляпа. Фотография собаки корги, едущей на велосипеде на Таймс-сквер. На нем солнцезащитные очки и пляжная шляпа. Плюшевые мишки плавают на Олимпийских играх в беге баттерфляем на 400 м. Плюшевые мишки плавают на Олимпийских играх в беге на 400 м баттерфляем. текст «Imagen», выходящий из книги сказок. Прозрачная скульптура утки из стекла. Скульптура находится перед картиной пейзажа. Прозрачная скульптура утки из стекла. Скульптура стоит перед картиной с пейзажем. Единственный луч света входит в комнату с потолка. Луч света освещает мольберт. На мольберте картина Рембрандта с изображением енота. Единственный луч света входит в комнату с потолка. Луч света освещает мольберт. На мольберте картина Рембрандта с изображением енота.
Визуализация Imagen. Imagen использует большой замороженный кодировщик T5-XXL для кодирования входного текста во встраивание. Модель условной диффузии отображает встраивание текста в изображение размером 64×64. Imagen также использует текстовые модели диффузии сверхвысокого разрешения для увеличения разрешения изображения до 64×64→256×256 и 256×256→1024×1024.
Мы показываем, что большие предварительно обученные кодировщики замороженного текста очень эффективны для задачи преобразования текста в изображение.
Мы показываем, что масштабирование размера предварительно обученного кодировщика текста более важно, чем масштабирование размера диффузионной модели.
Мы представляем новый пороговый диффузионный пробоотборник, который позволяет использовать очень большие направляющие веса без классификатора.
Мы представляем новую эффективную архитектуру U-Net, которая более эффективна с точки зрения вычислений, памяти и быстрее сходится.
На COCO мы достигаем нового современного COCO FID 7,27; и оценщики-люди считают, что образцы Imagen не уступают эталонным изображениям с точки зрения выравнивания изображения и текста.
Imagen представляет новый современный COCO FID.
Модель
COCO FID ↓
Обучение на COCO
AttnGAN (Xu et al., 2017)
35,49
DM-GAN (Zhu et al. , 2019)
32,64
DF-GAN (Тао и др., 2020)
21,42
DM-GAN + CL (Ye et al., 2021)
20,79
XMC-GAN (Zhang et al., 2021)
9,33
ЛАФИТ (Чжоу и др., 2021)
8,12
Make-A-Scene (Gafni et al., 2022)
7,55
Не обучался работе с COCO
DALL-E (Рамеш и др., 2021)
17,89
GLIDE (Nichol et al., 2021)
12,24
ДАЛЛ-Э 2 (Рамеш и др., 2022)
10,39
Imagen (наша работа)
7,27
Параллельная оценка человека.
Систематически проверяйте: композиционность, кардинальность, пространственные отношения, объемный текст, редкие слова и сложные подсказки.
Оценщики-люди категорически предпочитают Imagen другим методам как с точки зрения выравнивания изображения и текста, так и с точки зрения точности изображения.
Диффузионные модели добились большого успеха в генерации изображений [1, 2, 3, 4]. Модели авторегрессии [5], GAN [6, 7] Методы на основе VQ-VAE Transformer [8, 9] добились значительного прогресса в исследованиях преобразования текста в изображение. Совсем недавно модели Diffusion были исследованы для генерации текста в изображение [10, 11], включая параллельную работу DALL-E 2 [12]. DALL-E 2 использует предварительную диффузию для скрытых CLIP и модели каскадной диффузии для создания изображений с высоким разрешением 1024×1024. Мы считаем, что Imagen намного проще, так как Imagen не требует изучения латентного априорного анализа, но при этом достигает лучших результатов как в MS-COCO FID, так и в параллельной оценке человеком на DrawBench. GLIDE [10] также использует каскадные модели диффузии для преобразования текста в изображение, но Imagen использует более крупные предварительно обученные замороженные языковые модели, которые, как мы обнаружили, играют важную роль как для точности изображения, так и для выравнивания изображения и текста. XMC-GAN [7] также использует BERT в качестве текстового кодировщика, но мы масштабируем текстовые кодировщики гораздо большего размера и демонстрируем их эффективность. Использование каскадных моделей диффузии также популярно в литературе [13, 14] и успешно используется в моделях диффузии для создания изображений с высоким разрешением [2, 3]. Наконец, Imagen является частью серии работ по преобразованию текста в изображение в Google Research, включая родственную модель Parti.
Существует несколько этических проблем, с которыми сталкиваются исследования преобразования текста в изображение в целом. Мы предлагаем более подробное исследование этих проблем в нашей статье и предлагаем краткую версию здесь. Во-первых, последующие приложения моделей преобразования текста в изображение разнообразны и могут сложным образом влиять на общество. Потенциальные риски неправильного использования вызывают опасения в отношении ответственного открытого исходного кода кода и демонстраций. В настоящее время мы решили не выпускать код или публичную демонстрацию. В будущей работе мы изучим структуру ответственной экстернализации, которая уравновешивает ценность внешнего аудита с рисками неограниченного открытого доступа. Во-вторых, требования к данным для моделей преобразования текста в изображение вынуждают исследователей в значительной степени полагаться на большие, в основном некурируемые наборы данных, извлеченные из Интернета. Хотя этот подход позволил в последние годы добиться быстрого прогресса в алгоритмах, наборы данных такого рода часто отражают социальные стереотипы, репрессивные точки зрения и уничижительные или иным образом вредные ассоциации с маргинализованными группами идентичности. Хотя подмножество наших обучающих данных было отфильтровано для удаления шума и нежелательного контента, такого как порнографические изображения и оскорбительные выражения, мы также использовали набор данных LAION-400M, который, как известно, содержит широкий спектр неприемлемого контента, включая порнографические изображения, расистские оскорбления и вредные социальные стереотипы. Imagen полагается на текстовые кодировщики, обученные на некурируемых данных веб-масштаба, и, таким образом, наследует социальные предубеждения и ограничения больших языковых моделей. Таким образом, существует риск того, что Imagen закодировал вредные стереотипы и представления, что определяет наше решение не выпускать Imagen для публичного использования без дополнительных мер безопасности.
Наконец, в то время как была проведена обширная работа по аудиту моделей преобразования изображения в текст и маркировки изображений для форм социальной предвзятости, было сравнительно меньше работы над методами оценки социальной предвзятости для моделей преобразования текста в изображение. Концептуальный словарь потенциального вреда моделей преобразования текста в изображение и установленные метрики оценки являются важным компонентом разработки ответственных практик выпуска моделей. Хотя мы оставляем углубленный эмпирический анализ социальных и культурных предубеждений на будущее, наши небольшие внутренние оценки выявили несколько ограничений, которые определяют наше решение не выпускать нашу модель в настоящее время. Imagen может столкнуться с опасностью отказа от режимов распределения данных, что может еще больше усугубить социальные последствия предвзятости набора данных. Imagen имеет серьезные ограничения при создании изображений, изображающих людей. Наши человеческие оценки показали, что Imagen получает значительно более высокие показатели предпочтения при оценке изображений, на которых не изображены люди, что указывает на ухудшение качества изображения. Предварительная оценка также предполагает, что Imagen кодирует несколько социальных предубеждений и стереотипов, в том числе общую предвзятость в отношении создания изображений людей с более светлым оттенком кожи и тенденцию к тому, чтобы изображения, изображающие разные профессии, соответствовали западным гендерным стереотипам. Наконец, даже когда мы фокусируем внимание поколений на людях, наш предварительный анализ показывает, что Imagen кодирует ряд социальных и культурных предубеждений при создании изображений действий, событий и объектов. Мы стремимся добиться прогресса в решении некоторых из этих открытых проблем и ограничений в будущей работе.
Художественная галерея с картинами Моне. Художественная галерея затоплена. Роботы ходят по художественной галерее, используя весла. Художественная галерея, где выставлены картины Моне. Художественная галерея затоплена. Роботы ходят по художественной галерее, используя доски для весла. Величественная картина маслом королевы енотов в красном французском королевском платье. Картина висит на богато украшенной стене, украшенной обоями. Величественная картина маслом королевы енотов в красном французском королевском платье. Картина висит на богато украшенной стене, украшенной обоями. Голубая сойка стоит на большой корзине с радужными макаронами. Голубая сойка стоит на большой корзине с радужными макаронами. Гигантская змея-кобра на ферме. Змея сделана из кукурузы. Гигантская змея-кобра на ферме. Змея сделана из кукурузы.
Chitwan Saharia * , William Chan * , Saurabh Saxena † , Lala Li † , Jay Whang † , Emily Denton, Seyed Kamyar Seyed Ghasemipour, Burcu Karagol Ayan, S. Sara Mahdavi, Rapha Gontijo Лопес, Тим Салиманс, Джонатан Хо † , Дэвид Флит † , Мохаммад Норузи *
* Равный вклад. † Основной вклад.
Мы благодарим Бена Пула за рецензирование нашей рукописи, ранние обсуждения и многочисленные полезные комментарии и предложения на протяжении всего проекта. Особая благодарность Кэти Мейер-Хеллстерн, Остину Таранго и Саре Ласло за помощь в внедрении важных ответственных методов искусственного интеллекта в этот проект. Мы ценим ценные отзывы и поддержку от Элизабет Адкисон, Зубина Гахрамани, Джеффа Дина, Йонгхуи Ву и Эли Коллинза. Мы благодарны Тому Смоллу за разработку водяного знака Imagen. Мы благодарим Джейсона Болдриджа, Хана Чжана и Кевина Мерфи за первоначальные обсуждения и отзывы. Мы признательны Фреду Алкоберу, Хибаку Али, Мариан Кроук, Аарону Донсбаху, Талси Доши, Тоджу Дьюку, Дугласу Эку, Джейсону Фрейденфельдсу, Брайану Габриэлю, Молли ФитцМоррис, Дэвиду Ха, Филипу Пархэму, Лоре Пирс, Эвану Рапопорту, Лорен за их усердную работу и поддержку. Скелли, Джонни Соракеру, Негару Ростамзаде, Виджаю Васудевану, Трис Варкентин, Джереми Вайнштейну и Хью Уильямсу за советы по проекту и помощь в процессе публикации. Мы благодарим Виктора Гомеса и Эрику Морейру за их постоянную и важную помощь в распределении ресурсов ТПУ. Мы также благодарим Шекуфеха Азизи, Харриса Чана, Криса А.