TrueColor GIF

TrueColor GIF (191.75КиБ) Была у меня такая задумка — попробовать сделать полноцветную GIF-анимацию. Сразу скажу, идея провалилась, к сожалению.

Мысль-то простая — каждый полноцветный кадр должен представлять из себя полноцветный GIF. Общеизвестно, что формат GIF поддерживает только 256 цветов. Не страшно, разбиваем картинку так, чтобы каждый кадр содержал в себе не более 256 цветов и ляпаем их каждый поверх другого без задержки, в конце получится полноцветное изображение. Несколько таких изображений с задержкой между ними — и готова анимация.

Разбиение для начала выбрал простое — исходя из площади покрытия, думал потом взяться за оптимизацию (выбирать площадь, потом брать все цвета, которые в ней содержатся), но этого не понадобилось, оказалось, что если поставить задержку между кадрами ноль, то каждый браузер всё равно будет отрисовывать анимацию с очень заметной на глаз задержкой. Кажется в спецификации вообще не определено что означает нулевая задержка:
Delay Time - If not 0, this field specifies the number of hundredths (1/100) of a second to wait before continuing with the processing of the Data Stream. The clock starts ticking immediately after the graphic is rendered. This field may be used in conjunction with the User Input Flag field.
Но и если поставить задержку в 1/100 секунды, браузеры всё так же неторопливо отрисовывают картинку. Нарезанные кадры я собирал через утилиту gifsicle, она ещё и оптимизирует изображение — ненужны мне области я заливал прозрачным цветом, gifsicle умеет такие области отбрасывать, что уменьшает размер изображения:
gifsicle --delay 0 --crop-transparency -O3 out/*.gif > out.gif
Жаль, что ничего не получилось. Всё-таки надо переходить на APNG.

Зато выяснились любопытные подробности. Не знаю как это выглядит в IE (негде попробовать), а вот FireFox и Chrome умеют, один раз отрисовав конечную анимацию, потом мгновенно доставать её из кеша на перезагрузке страницы. «Опера», как и следовало ожидать, постоянно перерисовает анимацию — стоит только вернуться на страницу с другого таба или прокрутить её обратно до анимированного изображения.
12 августа 2011 01:22

Pozadi (инкогнито)
12 августа 2011, 02:07

зато какой интересный эффект получился

MaxSt (инкогнито)
12 августа 2011, 11:28

Теоретически "без задержки" (0/100 секунд) означает отрисовать как можно быстрее. Но практически все разработчики браузеров считают, что разгонять анимацию до 1000fps и больше, загружая при этом процессор на 100% было бы глупо.

bolk (bolknote.ru)
12 августа 2011, 11:58, ответ предназначен MaxSt

Теоретически «без задержки» (0/100 секунд) означает отрисовать как можно быстрее.
Только теоретически, практически в стандарте это место просто опущено.
Но практически все разработчики браузеров считают, что разгонять анимацию до 1000fps и больше, загружая при этом процессор на 100% было бы глупо
Наложить 40 изображений и показать все разом — уже слишком для современных процессоров? :) Вы заблуждаетесь, это вообще не проблема.

MaxSt (инкогнито)
12 августа 2011, 13:42

72 человека проголосовало:
https://bugzilla.mozilla.org/show_bug.cgi?id=595671
Похожие жалобы можно найти и для других браузеров.

Современные процессоры конечно могут и 1000fps выжать, но когда вентилятор в ноутбуке начнет гудеть, только чтобы GIFы разгонять до бешенной скорости - это мало кому понравится...

bolk (bolknote.ru)
12 августа 2011, 14:20, ответ предназначен MaxSt

Современные процессоры конечно могут и 1000fps выжать
Этого делать не нужно. Все последовательные кадры GIF при каком-то пороговом значении в задержке нужно просто собирать в один.

MaxSt (инкогнито)
12 августа 2011, 16:01

В оригинале (стандарт CompuServe) так и задумывалось: последний кадр был действительно последним, анимация была однократной. Но с тех пор как GIF получил циклическую анимацию (стандарт Netscape2.0), за последним кадром снова идет первый...

Если все кадры "собрать" в один, то как быть если анимацию требуется повторить, причем допустим ровно 3 раза?

bolk (bolknote.ru)
12 августа 2011, 16:37, ответ предназначен MaxSt

Если все кадры "собрать" в один, то как быть если анимацию требуется повторить, причем допустим ровно 3 раза?
Если каких-то вменяемых задержек нет, то никак — считать статикой.

bolk (bolknote.ru)
12 августа 2011, 16:38, ответ предназначен MaxSt

В оригинале (стандарт CompuServe) так и задумывалось: последний кадр был действительно последним
Prooflink? Я никогда ничего такого в стандарте не видел.

MaxSt (инкогнито)
12 августа 2011, 20:44

Если считать статикой - то это будет нарушение формата. Ведь юзер создавал анимацию, и ожидает увидеть анимацию. Если вместо нее он увидит статическую картинку, будет писать жалобы, типа "в вашем браузере баг, он показывает последний кадр вместо анимации". И будет прав.

Насчет рrooflink - общеизвестно, что сначала GIF был статичным. В оригинальной спецификации от CompuServe нет ни слова о том, что за последним блоком надо возвращаться к первому, там также нет слов "cycle" или "loop". Если нет однозначных указаний о том, что делать после последнего блока, значит ничего.

bolk (bolknote.ru)
12 августа 2011, 20:50, ответ предназначен MaxSt

Ведь юзер создавал анимацию, и ожидает увидеть анимацию
Ну, если задержка между кадрами ноль, то он должен увидеть кадры с задержкой ноль, то есть статику, по сути.
Насчет рrooflink — общеизвестно, что сначала GIF был статичным.
GIF87 был статичным. Но вы написали «в оригинале (стандарт CompuServe) так и задумывалось: последний кадр был действительно последним, анимация была однократной». В GIF87 не было анимации вообще. Поэтому меня и смутила фраза про то, что последний кадр был последним.

MaxSt (инкогнито)
12 августа 2011, 22:50

Нет, это не будет статика, потому что какие-то миллисекунды по любому потратятся на скачивание, декомпрессию и отрисовку. Ведь таймер задержки стартует только после окончания отрисовки блока.

Опять же если юзер явно прописал, что анимация должна повториться 100 раз, и только потом остановиться, он именно это и ожидает увидеть. Делать что-то другое - значит обмануть его ожидания, он явно напишет bug report, и будет прав. Потому что он прописал "100 раз" в точном соответствии со спецификацией.

Под стандартом CompuServe я понимаю самый последнюю спецификацию, выпущенную CompuServe. Там все именно так - однократная анимация, последний кадр является действительно последним.

bolk (bolknote.ru)
13 августа 2011, 00:34, ответ предназначен MaxSt

Опять же если юзер явно прописал, что анимация должна повториться 100 раз, и только потом остановиться, он именно это и ожидает увидеть.
Конечно. Но если пользователь прописал задержку, которая явно выше его скорости восприятия, он должен увидеть статику. Так как анимацию на такой скорости он увидеть не в состоянии.
Под стандартом CompuServe я понимаю самый последнюю спецификацию, выпущенную CompuServe. Там все именно так - однократная анимация, последний кадр является действительно последним.
Последняя спецификация, выпущенная CompuServe — это GIF89a. Вот она: http://www.w3.org/Graphics/GIF/spec-gif89a.txt ( Copyright CompuServe Incorporated, Columbus, Ohio). Я ошибся, кстати, в 87a уже была анимация, задержки не было. Вроде как ничего с тех пор и не менялось особо. Я не прав?

funk_rabbit (funk-rabbit.livejournal.com)
13 августа 2011, 00:38

100*(0/100)=0 статика и никаких обманов =) Действительно неприятный момент.

MaxSt (инкогнито)
13 августа 2011, 01:19

Кто-то может в состоянии увидеть, а кто-то может нет - в любом случае это не значит, что разрешается грубо нарушать спецификацию. Если спецификация требует отрисовать все кадры, и повторить этот цикл 100 раз, значит это и надо делать.

bolk (bolknote.ru)
13 августа 2011, 11:45, ответ предназначен MaxSt

Никто не в состоянии увидеть кадры, меняющиеся с задержкой ноль, это физике противоречит. И спецификация обходит стороной значение задержки ноль, я же привёл цитату.

MaxSt (инкогнито)
13 августа 2011, 12:24

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

Общее время анимации: T = P + D, где
P - processing (декомпрессия кадров и вывод их на экран)
D - delay (0/100, 1/100, ...)

Общее время Т всегда будет больше 0, даже если задержка D определена как 0.

bolk (bolknote.ru)
13 августа 2011, 12:47, ответ предназначен MaxSt

Если мы договорились следовать логике, то смена кадров со скоростью ноль, это смена кадров со скоростью ноль, то есть пользователь не в состоянии должен быть их различить. А это = статика.

MaxSt (инкогнито)
13 августа 2011, 14:14

Да, но скорость кадров не будет ноль, даже если выставить задержку в 0.

Скорость кадров измеряется от начала одного кадра до начала другого.
А задержка измеряется от *конца* одного кадра до начала другого.

То есть это немного разные вещи.

bolk (bolknote.ru)
13 августа 2011, 14:42, ответ предназначен MaxSt

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

MaxSt (инкогнито)
13 августа 2011, 15:33

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

Не случайно этот верхний лимит реализован во *всех* без исключения браузерах.

Он настолько необходим на практике, что Мозилла даже своему собственному APNG не позволяет слишком разгоняться. По их же спецификации в APNG можно установить любую рациональную (n/m) задержку, но на практике в Firefox он упрется в тот же самый верхний лимит.

bolk (bolknote.ru)
13 августа 2011, 17:37, ответ предназначен MaxSt

крайне необходимое с практической точки зрения (чтобы вентилятор в ноутбуке не гудел, пока процессор пытается разогнать какой-то анимированный смайлик до максимума).
Мы уже это обсуждали. Не будет вентилятор гудеть из-за каких-то там GIFов. Вы в DOOM играли? Он шёл на 386 процессоре с частотой в десятки мегагерц, а сейчас за гигагерцы скоростью уже.
Не случайно этот верхний лимит реализован во всех без исключения браузерах.
Да просто оптимизацией и развитием GIF не занимается никто.
Он настолько необходим на практике, что Мозилла даже своему собственному APNG не позволяет слишком разгоняться. По их же спецификации в APNG можно установить любую рациональную (n/m) задержку, но на практике в Firefox он упрется в тот же самый верхний лимит.
При этом в Canvas я могу вывести пару сотен изображений без задержки. http://bolknote.ru/2011/06/29/~3302/#35

SiMM (mr-simm.livejournal.com)
13 августа 2011, 17:40

На самом деле это вполне возможно увидеть, время на декомпрессию и прорисовку все равно ведь тратиться.
В спецификации указано время, которое должно тратиться на декомпрессию и прориовку? Если нет — то упоминание оного факта лишено смысла, хотя бы потому, что вчера на это тратилось 100 мс, а завтра — 1 мс, и это никак не противоречит спецификации. Как и здравый смысл, в общем-то.

MaxSt (инкогнито)
13 августа 2011, 19:29

Не так давно даже миниатюрный 16x16 throbber создавал проблемы для Firefox:
https://bugzilla.mozilla.org/show_bug.cgi?id=437829
Цитата оттуда из комментария 10:
The effect is that the fan of my laptop spins like crazy, while the laptop is drawing a simple animation.

Опять же, даже если они все супер-оптимизируют, какая-то разумная частота обновления Web-странички все же должна быть, правильно? Должен же CPU хоть немного отдыхать? Ведь если строго следовать спецификации, у CPU всегда будет работа: только успел отрисовать кадр, сразу начинай рисовать следующий...

bolk (bolknote.ru)
13 августа 2011, 19:46, ответ предназначен MaxSt

Неэффективно можно запрограммировать даже возврат из функции. А FireFox, который сейчас медленнее всех и жрёт памяти больше всех, мне кажется, совершенно не пример для подражания.
Должен же CPU хоть немного отдыхать?
Зачем? Он что, устаёт от этого? Ну и не работа это — вывести GIF, это очень быстро по нынешним меркам.

MaxSt (инкогнито)
13 августа 2011, 21:03

Если улучшить эффективность, анимация будет быстрей, но CPU будет так же работать без отдыха.

CPU должен отдыхать... в наще время пользователи тут же пишут bug report, если видят что программа ест 100% CPU без видимой надобности. Очень много людей сейчас работают на ноутбуках, и не хотят сажать батареи без крайней необходимости. Если они увидят что браузер занимает 100% CPU чтобы отобразить простую web-страничку, они его быстро деинсталлируют.

bolk (bolknote.ru)
14 августа 2011, 00:28, ответ предназначен MaxSt

Если улучшить эффективность, анимация будет быстрей, но CPU будет так же работать без отдыха.
Вы как-то аргументы мои не слышите. Вывести кучу гифок — это совсем не работа для современных CPU. Вспомните DOOM и вспомните на каком железе он шёл.
видят что программа ест 100% CPU без видимой надобности
А зачем его на 100% использовать? Для анимации каких-то гифок это без надобности.

MaxSt (инкогнито)
14 августа 2011, 01:08

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

DOOMу не требовалось загружать процессор на 100%, там тоже был верхний лимит на быстроту смены кадров, которую накладывал монитор. Если процессор успевал подготовить кадр быстрее, то остаток времени он просто ждал v-sync сигнала, ничего не делая.

bolk (bolknote.ru)
14 августа 2011, 01:21, ответ предназначен MaxSt

Это работа, если хочется выводить их с максимальной возможной скоростью. То есть спецификация требует, чтобы процессор был загружен на 100%, несмотря на то, насколько он мощный.
Ничего не понимаю. С чего вы взяли, что это потребует загрузки процессора на 100%? Задержка ноль вообще даст сначала небольшой всплеск нагрузки (на декодирование), а потом — нагрузка в пределах погрешности измерения.
DOOMу не требовалось загружать процессор на 100%
DOOM на многие порядки сложнее в обработке и нагрузке на CPU, чем вывод хоть сотни каких-то там гифов.

bolk (bolknote.ru)
14 августа 2011, 01:21, ответ предназначен MaxSt

Вы либо смеётесь надо мной, либо вообще не понимаете как всё работает.

MaxSt (инкогнито)
14 августа 2011, 10:47

Да, для декодирования хватит одного прохода, но наложение кадров друг на друга тоже ведь нагружает процессор. Если задача поставлена: не делать пауз, рисовать кадры постоянно, с максимально возможной скоростью, то такая задача нагрузит процессор на 100%. У процессора постоянно будет работа.

bolk (bolknote.ru)
14 августа 2011, 10:55, ответ предназначен MaxSt

Похоже вы действительно не понимаете как всё работает. Честно сказать, мне не хочется объяснять.

MaxSt (инкогнито)
14 августа 2011, 12:23

Я и так догадываюсь... Вам кажется что рисование кадров на экране - слишком тривиальная задача для современных процессоров. Это не совсем так. Зачем в погоне за титулом "самый быстрый браузер" они вдруг ринулись реализовывать hardware acceleration? Именно для того, чтобы разгрузить CPU от рисования графики.

bolk (bolknote.ru)
14 августа 2011, 18:57, ответ предназначен MaxSt

Я думаю не стоит продолжать этот разговор. Именно потому что я знаю подробности, а вы догадываетесь.

MaxSt (инкогнито)
14 августа 2011, 21:13

Как автор популярных конверторов gif2apng и apng2gif, я знаю подноготную достаточно хорошо. И не стал бы ставить этот эксперимент, потому что мне и так было бы ясно, чем он закончится.

Кстати, при обработке сайта на CPU рендеринг графики отнимает весьма существенную долю времени:
http://blogs.msdn.com/b/ie/archive/2010/08/30/performance-profiling-how-different-web-sites-use-browser-subsystems.aspx

bolk (bolknote.ru)
14 августа 2011, 23:03, ответ предназначен MaxSt

Как автор популярных конверторов gif2apng и apng2gif, я знаю подноготную достаточно хорошо.
Не вижу как это связано. Стандарт вы знаете хорошо, верю (и спасибо за конверторы, я хоть и не пользовался, но дело хорошее), но делать конверторы и понимать как всё работает на низком уровне — вещи разные.

MaxSt (инкогнито)
14 августа 2011, 23:25

Ну я же только что дал ссылку, там на достаточно низком уровне исследуется, какие модули браузера сколько CPU требуют, в частности рендеринг графики. Думаете, я не состоянии такие вещи понять?

bolk (bolknote.ru)
14 августа 2011, 23:45, ответ предназначен MaxSt

Не думаю. Но я работал с выводом графики, причём и на уровне ассемблера тоже, исследовал GPU и OpenGL, знаю что сколько занимает.

MaxSt (инкогнито)
15 августа 2011, 00:23

Ну так и я в выводом графики работал, и на ассеблере тоже. Но сейчас же не времена DOSа, когда можно было напрямую видеопямять адресовать. В браузере сначала куча слоев, потом куча библиотек, потом GDI, в итоге это нагромождение сильно тормозит.

bolk (bolknote.ru)
15 августа 2011, 01:44, ответ предназначен MaxSt

Нам не о чем дальше спорить.

funk_rabbit (funk-rabbit.livejournal.com)
11 сентября 2011, 13:48

а поподробнее можно, как делалась картинка выше?

bolk (bolknote.ru)
11 сентября 2011, 17:01, ответ предназначен funk_rabbit (funk-rabbit.livejournal.com):

Да я, вроде, описал уже всё. Считаем сколько какие-то цвета встречаются в картинке, сортируем по частоте использования. Разбиваем получившийся массив на отрезки по 255 цветов (256-й нужен для прозрачности). Всего будет общее количество цветов/255 кадров.

Для каждого отрезка на 255 создаём новый кадр с прозрачным фоном, в каждый кладём только те точки, цвета которых есть в выбранном нам отрезке.

masterspammer (masterspammer.livejournal.com)
17 августа 2012, 07:08

О! Ссылка на статью всплыла - http://habrahabr.ru/post/149728/#comment_5066608

Да, а про то, чтоб избавиться от эффекта прорисовки "по частям" - сделать "прогрессивный" GIF - первый кадр во весь экран, показывающий всего в 256 цветах, но всё, а потом - улучшающие его дополнительные.

bolk (bolknote.ru)
17 августа 2012, 08:14, ответ предназначен masterspammer.livejournal.com:

Забавно :)

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)