Привет, мир!
Я являюсь веб разработчиком. В процессе своей профессиональной деятельности мне приходится иметь дело с различными системами и платформами. Как показала практика, не всегда имеется возможность использовать полноценный инвайронмент, необходимый для обработки изображений. Как бы это ни было прискорбно, иногда приходится иметь дело с заказчиками, которые принципиально хостятся на определенной платформе с доисторическим софтом, а иногда, если это образовательное учреждение или еще какая-нибудь составляющая гос.системы, на своих серверах, доступа к которым нет ни у кого.
Задача
Что же делать в таком случае? Кажется возможным не связываться с такими проектами, но не всегда это возможно. Поставим задачу сделать облачную обработку изображений, в частности — ресайз. В рамках одного из условий задачи поставим необходимым ограничения в использовании процессорного времени и установленных графических библиотек на стороне клиента.
Решение
Около года назад у меня возникла необходимость в реалтайм генерации небольших превьюшек картинок фотогалереи на сайте одного образовательного учреждения. В рамках доступной возможности сохранения конфиденциальности не буду упоминать название этого заведения. Так вот, изображения загружаются из админ.панели, и в силу определенной специфики деятельности людей, занимающихся администрированием сайта, не предоставляется возможным принудить их менять размер картинок хотя бы до приемлемого минимума. Т.о. на входе мы имеем картинки размером до 10МБ, на выходе надо отображать их в виде небольшой легковесной галереи. Единственным возможным вариантом представлялась реализация кешируемого прокси сервера, который брал бы на себя всю головную боль ресайзинга изображений. Не долго думая, я сделал решение на NodeJS с использованием графической библиотеки ImageMagick. Это решение доступно для публичного использования по адресу http://thumber.io.
Особенность реализации
Отдельное внимание хочется уделить особенности хранения «кропнутых» картинок с использованием кеша, благодаря которому при повторном запросе уже обработанного изображения сам процессинг не будет запущен. Это позволяет сэкономить время повторной загрузки изображений. Кропнутые изображения хранятся на S3. Инвалидация кешируемого объекта будет произведена только в случае изменения его хеш-суммы или изменения заголовка etag. Для тех, кто не знаком с этим заголовком — https://ru.wikipedia.org/wiki/HTTP_ETag (пардон, если кому-то данная секция может показаться информацией для самых маленьких и тупых).
Примеры
В качестве примера использования могу привести обработку изображения, доступного по адресу
https://habrastorage.org/getpro/habr/comment_images/f22/27f/7d8/f2227f7d86053a207ebc88ae3377af4f.jpg:
Используя наше решение, мы можем сделать его ресайз, чтобы вписать изображение в область размером 200x200, используя следующий урл:
http://thumber.io/get/200x200/https://habrastorage.org/getpro/habr/comment_images/f22/27f/7d8/f2227f7d86053a207ebc88ae3377af4f.jpg
Результат обработки:
Думаю, интуитивно понятно, каким образом можно пользоваться обработкой подобного рода. В качестве параметра после /get/ можно использовать также процентное изменение. Например,
https://habrastorage.org/getpro/habr/post_images/1be/525/a7a/1be525a7a940f9e63705ffb1d4d9845e.jpg
Результат:
Гипотетически, возможно использование любого параметра ключа -resize утилиты convert. Более подробное описание использования возможностей мы разместили в небольшом документе, доступном по адресу http://thumber.io/Thumber.io.Documentation.pdf. Надеюсь, у желающих ознакомиться нет проблем с английским языком, и все будет понятно. Если что-то может требовать дополнительного пояснения, прошу задавать вопросы в комментарии.
Заключение
Прошел практически год с момента публикации данного решения. За это время были реальные примеры его использования в продакшне. Сейчас стоит вопрос в целесообразности плотной работы над данным направлением, его развитием, добавлением новых интересных фич, возможностей. Этот небольшой пост написан с целью сделать ресерч. Хабрасообщество, помогите принять решение. Есть ли у вас какие-нибудь мысли по поводу дальнейшего развития данного продукта и его прикладного использования?
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Комментарии (28)
vshemarov
23.01.2016 06:47+4Вот аналогичный сервис: uploadcare.com
Но у вас проще использовать, т.к. не требуется регистрироваться, заливать картинку, а потом ее тягать, достаточно просто подставить в УРЛ. Но в этом направлении, кстати, можно подумать с точки зрения монетизации: для использования так, как есть, оставить сервис бесплатным. Но предусмотреть и регистрацию юзеров, введя дополнительные фишки для них, и это уже сделать платным.
Как вариант: при бесплатном использовании хранить изображения в течение ограниченного времени (напр., месяц). Даже это будет большой плюс для тех, кто не хочет заморачиваться с ресайзом — прогнал картинку через ваш сервис при загрузке и сохранил у себя. А для платных хранить уже «вечно». В любом случае, если у сервиса будет расти популярность, то думать о монетизации придется, т.к. рано или поздно громадное хранилище картинок начнет требовать ощутимых ресурсов.
spmbt
23.01.2016 14:12+1Авторы, если не подошло это по причине онлайновости, image+resize+online, то почему сами предлагаете онлайн-сервис, без исходников? И чем не устроил Gimp + nginx?
>если… на своих серверах, доступа к которым нет ни у когоAdaStreamer
23.01.2016 14:19Вся суть в том, что мы предоставляем процессинг изображений в автоматическом режиме и нашему сервису абсолютно без разницы, где и кто пытается сделать ресайз. В основном, это как раз случаи, когда программист и понятия не имеет, что именно нужно ему будет обрабатывать. Вопрос исходников тут как раз не стоит остро — у грамотного специалиста не займет много времени написать подобного рода обработчик. С помощью нашего сервиса как раз и решается задача необходимости создания подобного обработчика.
spmbt
23.01.2016 18:06+1> задача необходимости создания
---другими словами, осознать, что нужно создание обработчика? Я же показал ссылку на Гугл, где то же самое делается в массе других решений. Т.е. осознать есть с помощью чего, а написать несложно. Так что ваш проект не решает уникальной задачи.AdaStreamer
23.01.2016 18:14Вы показали ссылку на Гугл, где в выдаче находятся ресурсы, позволяющее сделать ресайз, загрузив изображение вручную или указав ссылку на него. Такой подход можно использовать только если эти действия делать вручную. Мы же ставим задачу реализации такого сервиса в виде АПИ, где само использование может быть автоматизировано.
iSage
23.01.2016 14:16+1Ссылки вида thumber.io/get/1000000000x1000000000/https://habrastorage.org/getpro/habr/comment_images/f22/27f/7d8/f2227f7d86053a207ebc88ae3377af4f.jpg
успешно роняют ваше приложение. А ежели оно падает по таймауту — еще и забивают tmp, куда IM пишет временные файлы при расжатии.
Ну и, простейшим скриптом с перебором можно замусорить ваше хранилище достаточно быстро.AdaStreamer
23.01.2016 14:21Спасибо, на данном этапе мы надеялись на благоразумное использование. Если мы будем отправляться в большое плавание, косяки подобного рода обязательно будут устранены.
Mithgol
23.01.2016 15:00+2Можно сделать это решение строго джаваскриптовым, если от ImageMagick отказаться
в пользу JIMP.
Будет меньше накладных расходов на запуск внешнего (по отношению к Node.js) процесса, но чуть меньше производительность перекодировщика (JavaScript медленнее Си).AdaStreamer
23.01.2016 15:07В этом случае на клиент (в браузер) предварительно будет загружено исходное изображение. Если это 20 изображений по 5МБ, это существенно увеличит траффик.
Delphinum
23.01.2016 15:09+1Вы ошибаетесь. Вам предлагают заменить ваш серверный кропольщик с Сишного на JSшный, только и всего.
gene4000
23.01.2016 18:01+1Очень и очень полезная нужная вещь. Даже платно (если недорого:) можно использовать. Только тогда нужно будет добавить возможность заливки, без использования промежуточного сервера для хранения.
AdaStreamer
23.01.2016 18:06Спасибо. Внесем в список функционала возможность ручной заливки.
gene4000
23.01.2016 18:08Гм. Может быть мы слово «ручное» по-разному понимаем, но я говорил о каком-то api, например асинхронно на js что-то отправляется, а в ответ ссылка на файл приходит. А может через серверный скрипт, на php засылается. Я думаю, вы имели ввиду именно такой вариант, просто на всякий случай.
Evgeny42
23.01.2016 19:12+1Можно подумать еще над кропом. Например передавать соотношение сторон (ratio), или сами размеры, и если приспичит, то и позицию кропа. Включая как пиксели так и ключи, типа тех что есть у backgroud-position.
Ну и кеширование было бы здорово, на N минут с продлением, если например передавать какой-то ключ.
В общем можно много чего придумать, и все это довольно легко.
funca
23.01.2016 20:43+2Из софта есть еще опенсорсный thumbor.org — там REST API, умный кроп детекторами фич и физиономий через OpenCV, хранение на s3, дружелюбие к CDN и масштабируемость, опционально аплоад. Есть несколько рецептов для docker-compose, с помощью которых можно развернуть подходящую конфигурацию в облаке за полчаса.
Интересность вашего решения как сервиса зависит от SLA.
vladimirkolyada
25.01.2016 11:05+1https://cdn.thisislogic.ru наше детище. Используетя в продакш, не только ETag но и LastModified:) Хранится все… о боги в кластере Redis:) Доступность на данный момент простая, 2 канала и round robin. Проверяет изменение картинки на вашем сервисе в соответствии с правилом Last + опытным путем подобранным интервалом (что-то около 15 минут). Как пользоваться — все на странице написано.
AdaStreamer
25.01.2016 12:18А CDN — это действительно CDN? В каких регионах у вас датацентры?
vladimirkolyada
25.01.2016 13:04Есть такое на сафари и старых андроидах. Связано с тем, что они не умеют работать с несколькими сертификатами в пределах одного ip. Надо или выделять ip или ставить default сертификат с именем, которое надо поддерживать. Я хочу выделить ip, как отдельно появится возможность. По поводу датацентров — это сильно сказано. Это всего лишь 2 HP DL360 сервера:) Центральный регион, но не москва. Пока нет возможности расширяться, ведь проект некоммерческий. Простенькое тестирование можно запустить с LoadImpact, получить соответствующие выводы о приемлемости — доступности — скорости.
Delphinum
Необходимость подобных сервисов напрямую зависит от их доступности. Лично для меня сервис будет представлять интерес только в случае его бесплатности (во всех отношениях) и постоянной доступности. Многим еще захочется создать свою локальную копию. Идея вполне годная и нужная.
AdaStreamer
Никто не ведет речь о какой-либо оплате. В отношении доступности — согласен, надо предусмотреть возможные варианты балансировки, отказоустойчивости.
Delphinum
Ну это пока не ведет ) Было бы крайне печально перевести крупный проект на это решение, а затем узнать что оно стало платным. А монитизировать его понадобится, ибо без этого на постоянную доступность можно не расчитывать.
AdaStreamer
Соглашусь. В большинстве случаев подобные сервисы работают по схеме «Больше обращений — больше стоимость». Как пример могу привести prerender.io. Но тут тоже есть определенный смысл — больше обращений означает востребованность исходного ресурса. Большая востребованность означает возможность получения выгоды (если это не благотворительная деятельность), что допускает возможные расходы, пусть и минимальные, на одну из компонент своей инфраструктуры.
Delphinum
Значит вам нужно задуматься о бесплатных лицензиях для клиентов, занимающихся благотворительной деятельностью )