Разрешение и «Полу-пиксель» / Хабр
Изучив оба стандарта: IBM VGA и EXIF, написав пару публикаций по теме, у меня все равно ушло два дня, чтобы понять, откуда берется «полу-пиксель». И речь не о рендеринге сложных форм типа литер шрифта или иконок, а о стандартных ректанглах формата 100×100. Который по логике должен масштабироваться хорошо. Однако.
Полу-пиксель не новость. В любом редакторе, который умеет работать с вектором такие объекты как литеры шрифтов, иконки могут и будут, по своей форме, не совпадать с пиксельной сеткой.
В растровых же программах и в браузере применяются алгоритмы растеризации, которые заполняют соседние пиксели определенным оттенком в зависимости от занимаемой формой площади. С этим все давно понятно. Но откуда берется полу-пиксель у куба размером 105×105 px? И как это возможно? Разбираемся с матчастью.
Сценарий
Разрабатываешь ты интерфейсы и нужно в макет поставлять баннера или часть чужого интерфейса: фрейм apple music, spotify, платежки сбера и тд. Заходишь на сайт, где это можно взять и делаешь принтскрин. Принтскрин в Figm’у и….
… и все четенько, пиксель в пиксель. Баннер 300×600 px. Идем за следующим. Делаем принтскрин на том же устройстве, на том же сайте и странице и …
… полу-пиксель.
Эффект полу-пикселя можно получить в двух случаях: при целом значении размеров объекта и при дробном. Если при дробном параметре, как на виджете с яндекс музыкой, полу-пиксель напрашивается сам собой, то откуда он появляется при целом значении?
Спойлер: в обоих случаях имеем дело с увеличенным двукратно рендерингом логических пикселей. Но по порядку.
Раньше
До 2022 считалось, что у графического файла нет «разрешения». Оно конечно было, но использовалось только для печати, а в общей практики диджитал дизайнеров и верстальщиков отсутствовало. Ибо «до retina» и стандартизации DIP смысла в этом не было — не умели операционки, проф. софт и браузеры работать с этим параметром.
О путаннице в терминологии и понятии «Разрешение», я подробно уже писал в статье.
Во второй половине 2022 основные браузеры и проф ПО / Photoshop стали в полной мере поддерживать стандарт EXIF и научились работать с параметром “Resolution” почти как принтеры. И теперь Resolution по стандарту EXIF или Dancity по стандарту Material design , и «плотность пикселей» по русски, в полной мере используется в цифровых интерфейсах.
Разрешение / с одной стороны
Если на Retin’е сделать Принтскин, то параметры о разрешении запишутся в метаданные файла как 144 по высоте и 144 по ширине. Что соответствует двукратному увеличению от IBM стандарта в 72ppi.
На снимке у меня больше размер и разрешение, но в тексте использую стандартное соотношение.В самих параметрах файла будет указан размер по ширине и высоте, например 1440х900. Не стоит обманываться — это не реальный размер графического файла, а логический.
Если стереть метаданные в файле и открыть его в фотошопе, то мы увидим файл размером 2880х1800. И он будет пиксель в пиксель. Так уж логика у OSX.
А то разрешение, которое вы видите на мониторе, это вообще отдельная песня и к разрешению файла имеет косвенное отношение и к полу-пикселям тоже, поэтому опустим разговоры о разрешении монитора.
Если вы открывали такой принтскрин в фотошопе или в Figm’е в начале 2022 года, то он открывался бы как файл с размером 2880х1800 и там и там. Сегодня этот же принтскрин и в фотошопе или в Figma откроется как изображение 1440х1800.
Т.е. ПО научилось считывать данные о “resolution” и обрабатывать их, а точнее уменьшать изображение вдвое. Вдвое, потому, что Figma, значения отличные от 144 или 72 не понимает.
Браузер / с другой стороны
Браузеры же работают с логическими пикселями, перерисовывая изображение в двукратном увеличении от количества логических пикселей по ширине и высоте. Поэтому в свойствах объекта при просмотре кода появляется полу пиксель.
В случае с фреймом Яндекс музыки — это был бы полу-пиксель, если бы вы смотрели изображение с разрешением 72ppi и при выводе такого объекта линия бы сгладилась дорисовав в соседних пикселях оттенко. А для 144ppi это целый пиксель. Здесь надеюсь, понятно.
А вот пример с баннером хоть значение объекта и целое, при открытии файла в Figma тоже даст полу-пиксель. Откуда — спрашивается?
Во первых, если очистить метаданные и бросить файл в фигму, то он откроется никак 1440х1800, а в два раза больше — 2880х1800, и на этом изображении все будет четко — пиксель в пиксель. То же будет если метаданные не тереть, а просто двукратно увеличить размеры файта.
А вот в браузере не кратные двум значения объектов при определенных свойствах позиционирования, например в процентах или выровненные по центру, могут отрисовываться со смещением в 1 графический пиксель те половину логического. ведь математически для построения четкого изображения браузер работает с размером 2880х1800. да сам банер тоже рендерится в двукратном размере, но нечеткий параметр позиционирования например в 33% будет считаться и откругляться 2880х1800, а не от 1440х1800, что и может дать сдвиг на полпикселя.
P.
S.Под рукой нет устройства на винде с матрицей на 13-15 дюймов и 2/4к разрешением, чтобы посмотреть, как файлы пишет и масштабирует винда. Буду признателен за освещение этого вопроса в комментариях.
И с выравниваниями, позиционированием и алгоритмами рендеринга браузера мало экспериментировал. Такой эффект встречал только на не кратных двум параметрам. Если встречались другие случае появления полу-пикселя на ретинах, напишите пожалуйста в комментариях, проверю.
UP
По вопросам и дискуссии в комментариях отснял видео кейса. Всем спасибо за участие)
4. Сколько бит видеопамяти занимает информация об одном пикселе на ч/б экране (без полутонов)?([6],c. 143, пример 1)
Решение:
Если изображение Ч/Б без полутонов, то используется всего два цвета –черный и белый, т.е. К=2, 2i=2, I= 1 бит на пиксель.
Ответ: 1 пиксель
5. Какой объем видеопамяти необходим для хранения четырех страниц изображения, если битовая глубина равна 24, а разрешающая способность дисплея- 800 х 600 пикселей? ([6], №63)
Решение:
Найдем объем видеопамяти для одной страницы: 800*600*24=11520000 бит =1440000 байт =1406,25 Кб ≈1, 37 Мб
1,37*4 =5,48 Мб ≈5. 5 Мб для хранения 4 страниц.
Ответ: 5.5 Мб
Уровень «4»
6.Определить объем видеопамяти компьютера, который необходим для реализации графического режима монитора
Методические рекомендации:
Если ученик помнит, что режим High Color – это 16 бит на точку, то объем памяти можно найти, определив число точек на экране и умножив на глубину цвета, т.е. 16. Иначе ученик может рассуждать так:
Решение:
1. По формуле K=2I, где K – количество цветов, I – глубина цвета определим глубину цвета. 2I=65536
Глубина цвета составляет: I = log265 536 = 16 бит (вычисляем с помощью программы Wise Calculator)
2.
. Количество точек изображения равно: 1024´768 = 786 4323. Требуемый объем видеопамяти равен: 16 бит ´ 786 432 = 12 582 912 бит = 1572864 байт = 1536 Кб =1,5 Мб (»1,2 Мбайта. Ответ дан в практикуме Угринович). Приучаем учеников, переводя в другие единицы, делить на 1024, а не на 1000.
Ответ: 1,5 Мб
7. В процессе преобразования растрового графического изображения количество цветов уменьшилось с 65536 до 16. Во сколько раз уменьшится объем занимаемой им памяти? (2.70, [3]) Решение:
Чтобы закодировать 65536 различных цветов для каждой точки, необходимо 16 бит. Чтобы закодировать 16 цветов, необходимо всего 4 бита. Следовательно, объем занимаемой памяти уменьшился в 16:4=4 раза.
Ответ: в 4 раза
8. Достаточно ли видеопамяти объемом 256 Кбайт для работы монитора в режиме 640 ´ 480 и палитрой из 16 цветов? (2.77 [3]) Решение:
Узнаем объем видеопамяти, которая потребуется для работы монитора в режиме 640х480 и палитрой в 16 цветов. V=I*X*Y=640*480*4 (24 =16, глубина цвета равна 4),
V= 1228800 бит = 153600 байт =150 Кб.
150 < 256, значит памяти достаточно.
Ответ: достаточно
9. Укажите минимальный объем памяти (в килобайтах), достаточный для хранения любого растрового изображения размером 256 х 256 пикселей, если известно, что в изображении используется палитра из 216 цветов. Саму палитру хранить не нужно.
128
512
1024
2048
(ЕГЭ_2005, уровень А)
Решение:
Найдем минимальный объем памяти, необходимый для хранения одного пикселя. В изображении используется палитра из 216 цветов, следовательно, одному пикселю может быть сопоставлен любой из 216 возможных номеровцвета в палитре. Поэтому, минимальный объем памяти, для одного пикселя будет равен log2 216 =16 битам. Минимальный объем памяти, достаточный для хранения всего изображения будет равен 16*256*256 =24 * 28 * 28 =220 бит=220 : 23 =217 байт = 217 : 210 =27 Кбайт =128 Кбайт, что соответствует пункту под номером 1.
Ответ: 1
10. Используются графические режимы с глубинами цвета 8, 16. 24, 32 бита. Вычислить объем видеопамяти, необходимые для реализации данных глубин цвета при различных разрешающих способностях экрана.
Примечание: задача сводится в конечном итоге к решению задачи №1 (уровень «3», но ученику самому необходимо вспомнить стандартные режимы экрана.
11. Сколько секунд потребуется модему, передающему сообщения со скоростью 28800 бит/с, чтобы передать цветное растровое изображение размером 640 х 480 пикселей, при условии, что цвет каждого пикселя кодируется тремя байтами? (ЕГЭ_2005, уровень В)
Богатство, показанное в масштабе
185 миллиардов долларов (состояние Джеффа Безоса)
80 миллионов долларов
Джефф настолько богат, что это буквально невообразимо.
Мы редко видим имущественное неравенство, представленное в масштабе. Это одна из причин, по которой американцы постоянно недооценивают относительное богатство сверхбогатых.
Каждые 10 пикселей, которые вы прокручиваете, составляют 5 миллионов долларов.
Хорошо, теперь мы подходим к концу.
Лол, шучу, мы прошли примерно треть пути. Продолжайте прокручивать, есть еще что посмотреть.
Давайте рассмотрим это богатство в перспективе, сравнив его с некоторыми знакомыми вещами.
Даже состояния очень богатых людей меркнут перед непостижимым богатством 0,0001%.
Эти люди могут считать себя сказочно богатыми и часто выступают против политики, направленной на сокращение неравенства.
Но многие до конца не осознали огромную пропасть между собой и сверхбогатыми.
Мы можем иметь мир, в котором существуют богатые люди, не отдавая почти все деньги сверхбогатым.
Ни один человек не нуждается и не заслуживает такого богатства.
400 самых богатых американцев (3,2 триллиона долларов)
80 миллионов долларов
Джефф Безос может быть безумно богат, но это капля в море по сравнению с совокупным богатством его сверстников. 400 самых богатых американцев владеют примерно $3,2 трлн, что больше, чем у беднейших 60% американцев.
Триллион долларов — это такая большая цифра, что вы могли бы с тем же успехом сказать «одиннадцать гаджиллионов миллионов долларов». Итак, в этом разделе мы попытаемся понять масштаб этой цифры, посмотрев на то, что можно сделать с различными частями этого богатства.
Кто-то возразит, что использовать это богатство на благо общества невозможно, потому что оно «завязано» на запасы и поэтому недоступно. Это просто неправда.
Продолжая, постарайтесь помнить: все это богатство контролируется группой, настолько маленькой, что они могут поместиться в одном самолете Боинг-747 — с оставшимися 260 местами.
Что мы могли бы сделать с менее чем 10% этих денег?
Исходя из стоимости вакцин и стоимости доставки, для вакцинации каждого человека на земле потребуется около 200 миллиардов долларов, что составляет около 6% богатства, которое в настоящее время контролируется 400 американцами. После оплаты этой программы вакцинации эти люди все равно будут на 40 миллиардов долларов богаче, чем до пандемии.
Даже если оставить в стороне отчаянную гуманитарную потребность во всемирной вакцинации, все еще существует веский корыстный аргумент в пользу того, что ее должны сделать богатые страны: чем дольше ковид циркулирует в мире, тем больше шансов на появление и исчезновение устойчивой к вакцине разновидности весь прогресс в вакцинах, которого мы уже добились.
Всемирная организация здравоохранения в настоящее время организует глобальную программу пожертвований вакцин, цель которой — вакцинировать около 20% жителей бедных стран к концу 2021 года, но даже этот подход сопряжен со значительным дефицитом финансирования.
Малярия — одно из самых страшных инфекционных заболеваний, когда-либо поражавших человечество, от которого, возможно, погибло больше людей, чем от любого другого инфекционного заболевания в истории. Только в 20 веке малярия убила больше людей, чем Черная смерть.
Эти цифры становятся еще более шокирующими, когда вы узнаете, что малярия в подавляющем большинстве случаев убивает детей; около двух третей смертей от малярии каждый год приходится на детей в возрасте до пяти лет. Это около 275 000 детей.
Все из этих смертей можно предотвратить. Лечение и профилактика малярии — это хорошо изученная наука, широко применяемая в развитых странах.
Подсчитано, что к 2030 году малярию можно будет искоренить во всем мире при затратах около 1,84 доллара США на человека из группы риска в год, или около 100 миллиардов долларов США в целом. Это будет около 3% богатства, которым в настоящее время обладают 400 самых богатых американцев.
Сегодня от малярии умрут около 800 детей. Небольшая группа сверхбогатых людей могла бы остановить его за настолько маленькую сумму денег, что они, вероятно, даже не заметили бы его отсутствия. Но они предпочитают не делать этого.
Американцы имеют около 81 миллиарда долларов медицинского долга, который достаточно просрочен, чтобы появиться в их кредитном отчете. Как правило, это небольшие долги со средней стоимостью 207 долларов на человека.
Эти долги препятствуют кредитованию более 50 миллионов американцев и наносят долгосрочный ущерб их жилью, занятости и возможностям получения кредита. Стоимость погашения этого долга в соотношении доллар к доллару составит около 2,5% богатства, контролируемого 400 американцами.
Эта ситуация выглядит еще лучше, если вы понимаете, что просроченный долг часто покупается всего за 1% от его номинальной стоимости. Таким образом, общая стоимость устранения всех просроченных медицинских долгов составит около 810 миллионов долларов. В 2020 году 400 самых богатых американцев накапливали эту сумму примерно каждые 29 лет.часы.
Обратите внимание, что эта цифра включает только просроченных медицинских долгов, а не весь медицинский долг. Стоимость всех медицинских долгов в Америке публично неизвестна, но, вероятно, составляет около 300 миллиардов долларов, или 9% богатства, контролируемого 400 американцами.
По состоянию на 2021 год около 38 миллионов американцев жили в бедности. Если бы бедные американцы были штатом, они были бы вторыми по численности населения. В бедности живет больше американцев, чем все население Канады.
Каждый человек в Америке может подняться над чертой бедности с помощью единовременной денежной субсидии в размере около 10 000 долларов на обедневшую семью (и около 7 000 долларов на обедневшего человека). Общая стоимость составит 170 миллиардов долларов, что составляет немногим более 5% богатства, которое в настоящее время контролируется 400 людьми.
Может показаться нелогичным, что единовременная субсидия может иметь какое-либо долгосрочное влияние на хроническую бедность. Но одна из удивительных истин о бедности заключается в том, что она изменчива. Американцы впадают в бедность и выходят из нее много раз в течение своей жизни, и один хороший год может иметь огромный и долгосрочный эффект.
Огромное количество данных теперь поддерживает идею о том, что одноразовые денежные переводы могут навсегда преобразовать местную экономику. Получив неожиданный доход, люди инвестируют в свое будущее. Они возвращаются в школу, приобретают транспорт, оплачивают уход за детьми, выплачивают изнурительные долги и делают множество вещей, чтобы улучшить свои карьерные перспективы и финансовое будущее.
В США из всех людей, вырвавшихся из бедности в любой данный год, примерно половина остается вне бедности в течение как минимум пяти лет после этого. Около трети все еще не бедны десять лет спустя.
Это не будет постоянным решением для всех американцев. Несомненно, некоторые быстро вернутся в нищету, а другие столкнутся с такими большими долгами, что субсидия не будет иметь большого значения. Но для десятков миллионов американцев это событие изменило бы жизнь. Это будет определяющая поколения социальная программа, которая изменит нашу экономику на десятилетия вперед.
Около 844 миллионов человек не имеют доступа ни к какой чистой воде. Примерно столько же не имеют доступа ни к туалету, ни к туалету, и поэтому испражняются на открытом воздухе.
Отсутствие чистой воды
Загрязненная вода является основным источником болезней, включая холеру, дизентерию и брюшной тиф. Подсчитано, что загрязненная вода ежегодно убивает около 829 000 человек, что делает ее одной из крупнейших причин смерти в мире. Стоимость обеспечения чистой водой и удалением отходов для всех на земле составит около 240 миллиардов долларов, или 7,5% богатства, контролируемого 400 богатейшими американцами.
Хорошо, теперь, когда мы установили масштабы неравенства в Соединенных Штатах, давайте осмелимся мечтать о большем.
Что мы можем сделать с менее чем 40% этих денег?
Оплачиваемый отпуск по беременности и родам и отцовству оценивается примерно в 12 миллиардов долларов в год. Это 0,39% богатства, контролируемого 400 американцами. Это 5% от состояния, которое они накопили только в 2020 году.
Если бы они повторяли этот платеж каждый год в течение следующих 100 лет, это равнялось бы 39% богатства, которым они владеют сегодня.
Это более сложная программа для оценки, чем другие, рассмотренные на этой странице, потому что расходы будут постоянными, а не единовременными, а стоимость сильно варьируется в зависимости от размера предоставляемой выгоды. Тем не менее, используя правило выплаты пожертвований в размере 5%, сверхбогатые должны быть в состоянии финансировать программу отпусков по семейным обстоятельствам примерно в 12 раз более щедро, чем та, которая рассматривается здесь 9.0101 навсегда и все равно богатеть бесконечно, даже с учетом инфляции.
В Соединенных Штатах насчитывается около 128 миллионов домохозяйств. Чтобы дать каждому по 10 000 долларов, потребуется 1,28 триллиона долларов, или около 40% богатства, контролируемого 400 американцами.
Когда в 2020 году в Америке свирепствовал коронавирус, трудящиеся часто оказывались перед, казалось бы, невозможным выбором между смертью из-за преждевременного открытия и экономической депрессией, вызванной продолжающимся карантином. В этом ложном выборе не было высказано предположение, что американцы не могут оплачивать свои расходы на проживание без работы или неустойчивых государственных дефицитных расходов — откуда еще могли взяться деньги?
Что мы можем сделать с 60% этих денег?
Сочетание этих программ полностью изменило бы наш мир. Перераспределив это богатство, можно было бы спасти миллионы жизней. Миллиарды будут спасены от бедности и болезней. Доставив неудобства всего 400 людям , весь род человеческий мог бы выйти на новый, небывалый уровень развития.
И все из них все равно потом будут миллиардерами.
Неужели так радикально предположить, что это правильно? Учитывая выбор между миллионами смертей и небольшим сокращением состояния нескольких сверхбогатых людей, как можно было сделать вывод, что смерть миллионов предпочтительнее?
Мы больше не можем мириться с таким уровнем неравенства.
Как различные форматы изображений сжимают однопиксельные изображения
Пару месяцев назад, отдыхая от реализации новых интересных функций, таких как q_auto и g_auto, я шутил в нашем командном чате о том, насколько хорошо различные форматы изображений «сжимают» однопиксельное изображение. -пиксельные изображения. В ответ Орли, который ведет блог, спросил меня, не напишу ли я пост о однопиксельных изображениях. Я сказал: «Конечно, почему бы и нет. Но это будет очень короткая запись в блоге. В конце концов, мало что можно сказать об одном пикселе».
Похоже, я ошибся. Очень неправильно.
На заре Интернета изображения размером в один пиксель широко использовались в качестве решения бедняка для того, что мы сейчас делаем с помощью CSS. Интервалы, создание линий или прямоугольников, полупрозрачные фоны: вы можете многое сделать, просто масштабируя один пиксель до произвольных размеров. Другое использование однопиксельных изображений, до сих пор распространенное, — это веб-маяки для отслеживания или аналитики.
В адаптивном веб-дизайне однопиксельные изображения часто используются в качестве временных заполнителей во время загрузки страницы. Поскольку большинство браузеров не поддерживают клиентские подсказки, некоторые решения для адаптивных изображений ждут, пока страница полностью загрузится, чтобы определить фактические размеры визуализируемого изображения, а затем заменяют однопиксельное изображение правильным изображением точки останова с помощью JavaScript.
Существует еще одно применение однопиксельных изображений: их можно использовать в качестве изображений «по умолчанию». Если по какой-либо причине фактическое изображение, которое вы хотите показать, не может быть найдено, в некоторых случаях может быть лучше скрыть этот факт (показывая один прозрачный пиксель), чем возвращать ошибку «404 — Not Found», которая обычно будет отображается браузерами как значок «сломанного изображения». В обоих случаях вы не видите предполагаемое изображение, но оно может выглядеть немного более профессионально, если вы не «втираете» его, показывая значок сломанного изображения.
Хорошо, похоже, что однопиксельные изображения имеют некоторое применение. Итак, как лучше всего закодировать изображение 1×1?
Очевидно, это крайний случай для форматов сжатия изображений. Если «изображение» состоит только из одного пикселя, то данных для сжатия не так много. На самом деле несжатые данные составляют от одного бита до четырех байтов — в зависимости от того, как вы интерпретируете данные: черно-белое (1 бит), оттенки серого (1 байт), оттенки серого + альфа-канал (2 байта), RGB (3 байта), или RGBA (4 байта).
Но вы не можете кодировать только данные. В любом формате изображения необходимо указать, как интерпретировать данные. Как минимум, вам нужно знать ширину и высоту изображения, а также количество бит или байтов на пиксель.
Обычно для кодирования ширины и высоты используются четыре байта: по два байта на число (если бы это был только один байт, максимальный размер изображения был бы 255×255). Допустим, нам нужен еще один байт для кодирования типа цвета изображения (например, оттенки серого, RGB или RGBA).
В этом минималистичном формате изображения однопиксельное изображение будет занимать не менее 6 байт (например, для белого пикселя) и не более 9 байт.байт (для полупрозрачного пикселя произвольного цвета). Однако у реальных форматов изображений есть «заголовок», который содержит немного больше информации. Прежде всего, первые несколько байтов любого формата изображения содержат фиксированный идентификатор, который предназначен только для того, чтобы сказать «Привет! Я файл именно в этом формате!». Эта фиксированная последовательность байтов также известна как магическое число. Например, файл GIF всегда начинается либо с GIF87a
, либо с GIF89a
(в зависимости от используемой версии спецификации GIF), файл PNG всегда начинается с 8-байтовой последовательности, включающей
, файлы JPEG имеют заголовок, содержащий строку JFIF
или Exif
и так далее.
Заголовки могут содержать всевозможную метаинформацию об изображении. Часть информации относится к конкретному формату и указывает, какой подформат используется, и необходима для правильного декодирования пикселей. Некоторым из них может не понадобиться декодировать пиксели, но все же полезно знать, как их визуализировать, например. цветовые профили, ориентация, гамма или количество точек на пиксель. Некоторые из них могут быть произвольными метаданными, такими как комментарии, временные метки, уведомления об авторских правах или GPS-координаты. Эти вещи могут быть необязательными или обязательными; это зависит от спецификации формата. Конечно, все эти метаданные имеют некоторую стоимость с точки зрения размера файла. Итак, давайте сосредоточимся на «минимальных» файлах, из которых удалены все необязательные метаданные. В противном случае мы могли бы тратить драгоценные байты на глупости.
Помимо заголовков, форматы изображений могут иметь другие виды «накладных расходов». Они могут содержать всевозможные маркеры и контрольные суммы, предназначенные для повышения надежности формата в случае ошибок передачи или других форм повреждения. Кроме того, иногда требуется какое-то дополнение, чтобы обеспечить правильное выравнивание данных.
Однопиксельные изображения — наименьшие из возможных изображений — точно показывают, сколько «накладных расходов» содержится в формате изображения. Давайте взглянем.
Вот шестнадцатеричный дамп 67-байтового PNG-файла, представляющего белый пиксель 1×1:
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR| 00000010 00 00 00 01 00 00 00 01 01 00 00 00 00 37 6e f9 |.............7n.| 00000020 24 00 00 00 0a 49 44 41 54 78 01 63 68 00 00 00 |$....IDATx.ch...| 00000030 82 00 81 4c 17 d7 df 00 00 00 00 49 45 4e 44 ae |...L.......IEND.| 00000040 42 60 82 |Б`.|
Этот файл состоит из 8-байтового магического числа PNG, за которым следует фрагмент заголовка (IHDR), содержащий 13 байтов, фрагмент данных изображения (IDAT) с 10 байтами «сжатых» данных изображения и конечный маркер (IEND ). Каждый фрагмент начинается с 4-байтовой длины фрагмента и 4-байтового идентификатора фрагмента и заканчивается 4-байтовой контрольной суммой фрагмента, и эти три фрагмента являются обязательными, так что это еще 36 байтов для общего размера файла 67 байт.
Черный пиксель также имеет размер 67 байт в формате PNG; полностью прозрачный пиксель занимает 68 байт, а произвольный цвет RGBA будет иметь размер от 67 до 70 байт.
JPEG имеет более длинный заголовок. Наименьший однопиксельный JPEG составляет 160 байт (обновление: 141 байт). И он не может быть прозрачным, потому что JPEG не поддерживает альфа-канал.
GIF является самым компактным (с точки зрения заголовков) среди трех повсеместно поддерживаемых форматов изображений. Белый пиксель можно закодировать как действительный файл GIF всего за 35 байт:
00000000 47 49 46 38 37 61 01 00 01 00 80 01 00 00 00 00 |GIF87a..........| 00000010 ff ff ff 2c 00 00 00 00 01 00 01 00 00 02 02 4c |...,...........L| 00000020 01 00 3b |..;|
и полностью прозрачный пиксель можно сделать в 43 байта:
00000000 47 49 46 38 39 61 01 00 01 00 80 01 00 00 00 00 |GIF89a..........| 00000010 ff ff ff 21 f9 04 01 0a 00 01 00 2c 00 00 00 00 |...!.......,....| 00000020 01 00 01 00 00 02 02 4c 01 00 3b |. ......L..;|
Обратите внимание, что для всех вышеперечисленных форматов вы можете придумать еще меньшие файлы, которые все равно будут декодироваться в однопиксельное изображение во всех или большинстве браузеров, но они недействительны в отношении спецификаций формата, а это означает, что декодер изображений может в любой момент пожаловаться (правильно), что файл поврежден, и показать значок поврежденного изображения, которого мы пытались избежать.
Итак, какой формат для однопиксельного изображения лучше всего подходит для Интернета? Это зависит от. Если это непрозрачный пиксель, то ответ — GIF. Если это полностью прозрачный пиксель, то ответ тоже GIF. Но если это полупрозрачный пиксель, то ответ — PNG, поскольку GIF поддерживает только прозрачность «все или ничего».
Не то, чтобы все это имело большое значение. Все эти файлы легко умещаются в одном сетевом пакете, так что на практике реальной разницы в скорости нет — да и хранилище, необходимое для этого, в любом случае ничтожно мало. Но, тем не менее, это забавная вещь, по крайней мере, для фанатов формата изображений, таких как я.
Если вы используете WebP для однопиксельных изображений, обязательно используйте WebP без потерь. Однопиксельное изображение WebP без потерь имеет размер от 34 до 38 байт. Однопиксельное изображение WebP с потерями имеет размер от 44 до 104 байт, в основном в зависимости от того, есть ли альфа-канал или нет. Например, это полностью прозрачный пиксель в виде 34-байтового без потерь WebP:
00000000 52 49 46 46 1a 00 00 00 57 45 42 50 56 50 38 4c |RIFF....WEBPVP8L| 00000010 0d 00 00 00 2f 00 00 00 10 07 10 11 11 88 88 fe |..../...........| 00000020 07 00 |..|
, а здесь тот же пиксель, что и с потерями (по умолчанию) WebP из 82 байт:
00000000 52 49 46 46 4a 00 00 00 57 45 42 50 56 50 38 58 |RIFFJ...WEBPVP8X| 00000010 0a 00 00 00 10 00 00 00 00 00 00 00 00 00 41 4c |.............AL| 00000020 50 48 0b 00 00 00 01 07 10 11 11 88 88 fe 07 00 |PH.......... ....| 00000030 00 00 56 50 38 20 18 00 00 00 30 01 00 9д 01 2а |..ВП8 ....0....*| 00000040 01 00 01 00 02 00 34 25 a4 00 03 70 00 fe fb fd |......4%...p....| 00000050 50 00 |П.|
Основное различие между ними заключается в том, что WebP с потерями и прозрачностью фактически хранится внутри в виде двух изображений, объединенных в один файл-контейнер: одно изображение с потерями для значений RGB и одно изображение без потерь для значений альфа-канала.
Для формата BPG Белларда, который также имеет режим без потерь и режим с потерями, все наоборот. Кодирование BPG с потерями одного белого пикселя составляет 31 байт, это наименьший из тех, что мы видели до сих пор:
00000000 42 50 47 fb 00 00 01 01 00 03 92 47 40 44 01 c1 |BPG........G@D..| 00000010 71 81 12 00 00 01 26 01 af c0 b6 20 bc b6 fc |q.....&.... ...|
BPG без потерь для того же белого пикселя составляет 59 байт. Однако полностью прозрачный пиксель составляет 57 или 113 байтов как BPG с потерями или без потерь соответственно. Интересно, что для одного белого пикселя BPG выигрывает у WebP (31-байтовый BPG против 38-байтового WebP), но для одного прозрачного пикселя WebP выигрывает у BPG (34-байтовый WebP против 57-байтового BPG).
А еще есть FLIF. Как основной создатель формата Free Lossless Image Format, я, очевидно, не могу забыть об этом. Вот 15-байтовый FLIF-файл для одного белого пикселя:
00000000 46 4c 49 46 31 31 00 01 00 01 18 44 c6 19 c3 |FLIF11.....D...|
А вот 14-байтовый файл для черного пикселя:
00000000 46 4c 49 46 31 31 00 01 00 01 1e 18 b7 ff |FLIF11........|
Файл черного пикселя на один байт меньше, потому что число ноль сжимается лучше, чем число 255. Заголовок довольно прост: первые четыре байта всегда «FLIF», следующий байт представляет собой удобочитаемое указание цвет и тип переплетения. В данном случае это «1», что означает, что у нас есть только один цветовой канал (то есть это изображение в градациях серого). Следующий байт указывает глубину цвета: «1» означает один байт на канал. А следующие четыре байта — это размеры изображения, в данном случае 0x0001 на 0x0001. Последние четыре или пять байтов — это фактически сжатые данные.
Один полностью прозрачный пиксель также занимает 14 байт во FLIF:
00000000 46 4c 49 46 34 31 00 01 00 01 4f fd 72 80 |FLIF41....O.r.|
В данном случае у нас 4 цветовых канала (RGBA) вместо одного. Вы можете ожидать, что раздел данных в этом файле будет длиннее (в конце концов, цветовых каналов в четыре раза больше), но это не так: поскольку альфа-значение равно нулю (это полностью прозрачный пиксель), RGB значения считаются нерелевантными, поэтому они вообще не кодируются.
Для произвольного цвета RGBA файл FLIF может иметь размер до 20 байт.
Итак, FLIF — явный победитель в категории «один пиксель» какого-то странного соревнования по кодированию изображений. Если бы это было важно, чтобы конкурировать на 🙂
На самом деле, нет. FLIF не является победителем. Помните минималистичный (и несуществующий) формат изображения, о котором я упоминал в начале? Тот, который кодировал бы однопиксельные изображения размером от 6 до 9 байт? Такого формата не существует, поэтому я полагаю, что он не считается. Но существует формат изображения, который очень близок к этому.
Он называется Portable Bitmap format (PBM) и представляет собой несжатый формат изображения 1980-х годов. Вот как вы можете закодировать один белый пиксель в файл PBM всего за 8 байтов:
00000000 50 31 0a 31 20 31 0a 30 |P1.1 1.0|
На самом деле, забудьте о шестнадцатеричном дампе, это человекочитаемый формат файла. Вы можете открыть его в текстовом редакторе, если хотите (по крайней мере, этот конкретный подформат):
P1 1 1 0
Первая строка («P1») указывает, что это черно-белое изображение. Не оттенки серого; есть только два цвета: черный (который сбивает с толку число 1) и белый (0). Во второй строке указаны размеры изображения. А затем это просто список чисел, разделенных пробелами, по одному числу на пиксель. Так что в данном случае просто число 0.
Если вам нужно что-то другое, кроме чисто белого или черного, вы можете использовать формат PGM, чтобы получить один пиксель любого другого оттенка серого всего за 12 байт, или формат PPM, чтобы получить любой цвет RGB всего за 14 байт. Он всегда меньше, чем соответствующий файл FLIF (или любой другой сжатый формат, если уж на то пошло).
Традиционное семейство PNM (PBM, PGM и PPM) не поддерживает прозрачность. Однако существует расширение PNM, называемое Portable Arbitrary Map (PAM), которое поддерживает изображения с прозрачностью. К сожалению, для наших текущих целей его синтаксис немного более многословен. Наименьший допустимый файл PAM, который кодирует полностью прозрачный пиксель, следующий:
Р7 ШИРИНА 1 ВЫСОТА 1 ГЛУБИНА 4 МАКСВАЛ 1 TUPLTYPE RGB_ALPHA КОНЕЦHDR \0\0\0\0
В последней строке четыре нулевых (NULL) байта. Приведенный выше файл имеет размер 67 байт. У вас может возникнуть соблазн использовать оттенки серого + альфа вместо RGBA, потому что это сэкономит два байта в разделе данных. Но это приводит к 71-байтовому файлу, поскольку вам нужно изменить TUPLTYPE
с RGB_ALPHA
на GRAYSCALE_ALPHA
. Да, и, кстати, вашему программному обеспечению для работы с изображениями может не понравиться использование MAXVAL 1
, поэтому вам может понадобиться изменить его на MAXVAL 255
(что занимает еще два байта).
Итак, в целом, для однопиксельных изображений, когда не используется прозрачность, PNM является наименьшим (8–14 байтов для PNM против 14–18 байтов для FLIF), но когда есть прозрачность, FLIF наименьший (14 до 20 байт для FLIF и от 67 до 69 байт для PAM).
Вот сводная таблица, в которой указаны (оптимальные) размеры файлов для различных однопиксельных изображений:
белый | черный | серый | желтый #FFFF00 | прозрачный | полупрозрачный #1337BABE | |
PNG | 67 | 67 | 67 | 69 | 68 | 70 |
GIF | 35 | 35 | 43 | 35 | 43 | / |
JPEG | 160 | 160 | 159 | 288 | / | / |
WebP с потерями | 44 | 44 | 44 | 64 | 82 | 92 |
WebP без потерь | 38 | 34 | 38 | 36 | 34 | 38 |
BPG с потерями | 31 | 31 | 29 | 36 | 57 | 62 |
BPG без потерь | 59 | 59 | 37 | 124 | 113 | 160 |
ФЛИФ | 15 | 14 | 15 | 18 | 14 | 20 |
ПНМ/ПАМ | 8 | 8 | 12 | 14 | 67 | 69 |
Может показаться немного удивительным, что несжатый формат изображения на самом деле превосходит большинство сжатых форматов в этой конкретной задаче.