Pull to refresh

Comments 42

Почему приписка к картинке с JPEG «без видимой потери качества.» если по контуру здания на второй фотке появились артефакты сжатия?
Во первых да, примеры для статьи я пережимал с качеством 80, т.к. оно дает хорошее соотношение качество/объем. Естественно можно использовать более высокие настройки качества.
Во вторых артефакты, о которых вы говорите, я заметил только при 500% увеличении картинки в браузере, но ее увеличение не предполагается.
Все зависит от глаз, монитора, освещения и других факторов… Мне видны артефакты без увеличения картинки.
PS: Однажды долго доказывал автору скина аудиоплеера что на его черном скине имеются две слегка белые полосы. Он никак не мог понять где это, пока я не выложил картинку с задранным контрастом и яркостью…
Я вот не вижу никаких «артефактов по контуру здания», зато очень хорошо вижу, что небо превратилось в «мозаику» из таких слоистых «кусков». Довольно-таки неприятный эффект.
Только не надо путать ресайз с жатием изображения. Ресайз подразумевает изменение размера изображения — изменение высоты и ширины. И у ресайза есть свои проблемы и их решения.
Так я как раз и говорю о том, что для использования в вебе желательно не только ресайзить изображения, но и пережимать, потому что это может существенно сократить размер картинки. В своем решении мы совмещаем ресайз и пережатие, потому что только ресайз выдает достаточно большие по объему изображения.
в примерах картинки только с жатием, размер оставлен без изменения. И о проблемах при ресайзе ни слова — а это отдельная тема для большого разговора. Не надо путать людей заголовками.
Да, тоже зашел читать про ресайз — заголовок сбивает с толку. Статья при этом интересная, спасибо!
С png разница может быть еще заметнее. Разница в размере почти в 7 раз.

Качество — ужас.
Ага. Не «возможно появление артефактов», а есть жуткие артефакты, видимые (на небе) невооруженным глазом.
Спасибо, действительно не самый удачный пример и на некоторых картинках пережатие работает не очень хорошо. Добавил пример хорошей картинки и немного поменял описание.
Пробывали модуль для nginx — google pagespeed?
В нем есть отличный оптимизатор картинок вплоть до конвертации в WebP для современных браузеров.
Мы используем ngx_http_image_filter_module для ресайза и pagespeed для оптимизации. Нагрузка минимальна. Полученные картинки конечно кешируются в pagespeed
А у вас он проксирует весь трафик или отдельный инстанс, который занимается только ресайзом? Какую примерно нагрузку он держит с кэшированием и без?
У нас в принципе картинки ходят через отдельный инстанс. В настройках включена только оптимизация изображений. Без кеширования его включить нельзя. У него асинхронная модель оптимизации. На первый просмотр он всегда отдает оригинал.
Удобно тем что разным клиентам отдает разные оптимизации. Кому-то webP, а кому-то оптимизированный jpeg. Ну и конечно все рекомендованные оптимизации от гугла из коробки.

Сейчас пробывал очистить кеш pagespeed. На секунд 30 nginx скушал 4 ядра процессора и создал 1 гигабайт кеша за это время. После этого нагрузка сразу упала до привычных 20-30% У нас примерно по 200rps показы картинок. Но это веб сайт — кеширование результатов ресайза очень эффективно(больше 99% из кеша берется).
Мы естественно тоже кешируем результаты nginx'ом, но бывают например, что приходит какой то трафик на старые страницы, для которых кэша нет или сбросился кэш. Отсюда интерес к производительности без кеша.
Чем нам не понравилось решение на nginx- накрутить нашу логику в конфиге можно, но выглядеть это будет очень уж страшно. Новых проектов это конечно не касается, там больше свободы и можно и на nginx сделать красиво.
>> Чем нам не понравилось решение на nginx- накрутить нашу логику в конфиге можно, но выглядеть это будет очень уж страшно.
Ну я не знаю что страшней. 20 строк в конфиг nginx (локейшен для ресайза и парсинг аргументов — размеров + настройки кеша и pagespeed) или отдельный демон для ресайза.
Я конечно уверен что демон гибче и потому производительней. Но его ж нужно самим поддерживать, развивать и править баги.
В примере с jpeg разница между картинками действительно несущественна, хотя и можно заметить артефакты по границе башни, если присматриваться. А вот с png кошмар, картинка просто убита в хлам. И такая ситуация не «возможна», она стопроцентно будет, если ставить себе целью 7-кратный выигрыш веса.

Если вам критичен вес картинок на сайте, внедряйте webp. Насколько мне известно, дает выигрыш порядка 20-30% при сжатии с потерями относительно jpg и 10-15% без потерь относительно png. Это уже при условии что jpg/png хорошо оптимизированы.
Libvips дает возможность конвертировать картинки между разными форматами, в том числе в webp, но мы пока ей не пользуемся. За наводку спасибо, возможно стоит конвертировать в webp.
А если делать по-серьёзному — то перед сохранением картинок на сервере, рекомендую сделать страницу, где юзер может произвести кадрирование изображения, поворот, ресайз, и сделать «полноразмерную» картинку для просмотра, и превьюшку.
Немного не наш кейс, у нас это работает например для таких случаев: аватарка пользователя хранится и показывается в профиле в 200х200, но на страницах форума показывается в 150х150, а например на главной в 75х75. И все эти уменьшенные версии надо генерить автоматом. Кроп, кадрирование и прочие фичи там не нужны.
фишка в том что при простом уменьшении размера с 200*200 до 75*75 произойдёт ухудшение качества изображения.
Не очень понял, что вы имеете в виду под простым случаем. Часть информации мы при ресайзе естественно теряем, но это не должно ухудшать качество картинки «на глаз»(естественно если потом получившуюся картинку не растягивать до размера оригинала).
Если же это проявляется в заметных артефакт, то есть смысл смотреть на алгоритм ресайза и его настройки.
На всякий случай уточню предыдущий коммент: мы храним только оригиналы в максимальном используемом разрешении (200х200 в примере). Менее качественные версии генерируются динамически и только кешируются на некоторое время.
Второй момент: например про главную. 75х75 это размер, определяемый версткой страницы, то есть в верстке есть контейнер 75х75 пикселей и мы вставляем туда версию нужного размера. Мы естественно не вставляем 75 версию в 200 контейнер.
«Простой ресайз» это изменение за один раз с 200*200 до 75*75. для исключения потери качества при ресайзе необходимо производить уменьшение в несколько шагов. Поэтому лучше хранить превью и полный размер. Полный размер просматривается на всегда, и его можно загружать по требованию. на это много времени не потребуется. и кэш для превью занимает меньше места.
Естественно, мы так и делаем. В моем коде это работает так:
Вместо "/test.png" в том месте страницы, где нужна маленькая версия мы пишем "/test.png@75". Все запросы с @ в конце отправляются nginx'ом на ресайз бэкенд. Он в свою очередь пасит url, скачивает оригинал ("/test.png"), ресайзит его до нужного разрешения и отдает nginx'у. Nginx кэширует результат и отдает его клиенту.
Ещё раз ресайзить за один раз — не правильно. происходит потеря качества.
не только потеря информации, но и потеря качества. А у Вас нет ни слова о том как происходит ресайз, хотя в заголовке написано про ресайз. Может в конкретном случае при таком достаточно не большом изменении размера это не заметно, но это так. Мне пришлось этим заниматься когда автоматизировал загрузку фото товаров на сайт. Было необходимо иметь просмотровую картинку 600*700 и превью 60*70. Алгоритм был отработан. А увидев заголовок про ресайз, решил что могу подчерпнуть что-то новенькое… к сожалению не удалось.
и из Вашего описания не получается что маленькая картинка берётся из кэша.
Все запросы с @ в конце отправляются nginx'ом на ресайз бэкенд.
получается, что все превью всегда ресайзятся
Сожалею, что не рассказал Вам ничего нового.)
Все запросы с @ в конце отправляются nginx'ом на ресайз бэкенд.

Nginx кэширует ответы бэкенда, и при следующем запросе она отдается уже из кэша, а не с бэкенда. В readme в репе есть пример конфига Nginx, который реализует эту логику.
По поводу ресайза в несколько проходов. Не могли бы Вы рассказать как вы это делали и какой библиотекой? На первый взгляд похоже на проблему с алгоритмом ресайза, из-за которой он при большом изменении размера портил качество. Теоретически вариант, когда мы ресайзим большую в маленькую должен быть лучше, чем вариант, когда мы делаем «большая->средняя->маленькая», т.к. не происходит потери на шаге «большая->средняя».
Не могли бы Вы рассказать как вы это делали и какой библиотекой?
библиотеки нет, есть простой алгоритм вычисления шагов, который определяет сколько требуется шагов для уменьшения в 2 раза и один шаг (1,x раз )для уменьшения до размера, чтоб следующие шаги уменьшали равно в 2 раза. далее уменьшение в 1, х раз и далее n шагов уменьшения в 2 раза. Это проверено при уменьшении картинки полученной с камеры (примерно 2к*2к) до превьюшки 60*70. библиотеки я не нашёл, поэтому пришлось делать самому. Весь процесс такой: есть рамка просмотрового размера 600*700, в неё загружается фото товара с помощью перемещения, поворота, изменения размера в эту рамку вписывается та часть фото, которая наиболее информативна. происходит «обрезка» — получается «просмотровая» картинка, дальше устанавливаются границы для превьюшки и так же кадрируется, «обрезка» и в результате 2 картинки. В процессе «обрезки» и происходит вся магия преобразования
Это фигня из серии теплого лампового звука. Где-то когда-то что-то было, а теперь просто миф для «ценителей»
это к чему? к пошаговому ресайзу?
спорить не стану, потому как прошёл это сам — если не веришь (в отличии от лампового звука, где важен слух) можешь сделать «ресайз», но только именно ресайз разовым уменьшением в N раз.
Я к тому, что разница может быть, но будет она только для некоторых старых алгоритмов, например, с тупейшим nearest neighbour внутри (потому что умножение в те времена стоило дорого).
Современные алгоритмы, которые под векторные инструкции (SSE) спроектированы и написаны, в большинстве своём таких проблем не имеют. Можете взять какую-нибудь картинку в png (да хоть скриншот хабра) и сравнить побайтово результат уменьшения, скажем, в 10 или 20 раз одним махом или в 2-3 стадии.
тут дело не в векторных инструкциях. я ресайзил с помощью canvas, там алгоритмов как таковых нет. поэтому самый простой оказался с пошаговым уменьшением. и сравнивал с изменением в xnview с разными алгоритмами — если задавать разово большой коэффициент изменения — тоже качество страдает.
интересно, что если в браузере уменьшать визуально(просто меняя количество точек для отображения) — качество отличное
Ещё раз ресайзить за один раз — не правильно. происходит потеря качества.
Это очень сильно зависит от алгоритма масштабирования. Их много разных, от быстрых и грубых до медленных и качественных.
В разном ПО и библиотеках могут быть реализованы очень разные алгоритмы, нужно выяснять, где и какой именно.
Как примеры крайностей: в canvas ресайз очень сильно оптимизирован в сторону скорости, а качество полный шлак (там шаги насущная необходимость), в ФШ качество очень высокое (шаги — блажь и плацебо).
Не могу не поделиться. Недавно требовалось получить качественный пакетный downsample с больших (20-50-80 МП) оригиналов на 1080p и 2160p.
Взяв ФШ в качестве эталона, попробовал opencv lanczos — на удивление не айс. Перепробовал разные варианты на opencv, перешел на imagemagic, следуя ряду рекомендаций, например, www.bvdwolf.nl/foto/resample/down_sample.html, удалось улучшить результат. Лучший вариант получился с RGB компенсацией и sinc фильтром.
Но — ФШ все равно лучше! А пошаговое уменьшение в ФШ — еще лучше. Так и пришлось написать automation script пошагового уменьшения для ФШ. Хорошо, что сейчас это можно делать на питоне.
Если кому-то известно, как ФШ этого добивается, или как сделать не хуже — будет крайне интересно. Если интересно — могу поделиться подробностями и картинками. В целом, надеялся, что в 2018 году все уже решено — ан нет, похоже, что тема для хорошей магистерской.
Лично у меня наоборот, удивление вызывает широко распространенное мнение о крутизне Ланцоша. Почему все решили, что он должен быть качественнее? Потому что там функция мудреная и график красивый? По мне так понятно, что он будет чудить своими осцилляциями. Возможно, за исключением каких-то специфических ситуаций.

Ссылка любопытная, хотя тестовое изображение и сам тест кажутся слишком надуманными и искусственными.
странно. требуется производительность, многопоточность — и не используете GPU.
Кстати, да! Такая задача идеально ляжет на железо GPU.
а как вы используете SO_REUSE (PORT?) и --scale? scale же создает отдельные контейнеры с отдельными адресами

— А все увидел: вы запускаете контейнеры в хостовом netns
imlib2 не пробовали? Помнится у неё был оочень быстрый ресайз.
Судя по страничке Speed-and-memory-use libvips быстрее, но должен заметитить, что результаты imlib2 у них конечно немного странные и возможно они что то не докрутили. Более существенный, по моему мнению, недостаток imlib2- странная лицензия и достаточно маленькое комьюнити. Хотя погонять бенчмарк возможно все таки стоит.)
Судя по страничке Speed-and-memory-use

Скажите, зачем вы смотрите результаты, цитирую «load a TIFF image, crop 100 pixels off every edge, shrink by 10% with bilinear interpolation, sharpen with a 3x3 convolution and save again», если у вас задача качественно (то есть точно не bilinear) ресайзить в несколько раз (а не на 10%) JPEG (а не TIFF) и у вас нет шарпа, который занимает в данном тесте от 50 до 90% времени для разных библиотек?

Sign up to leave a comment.

Articles