Привет, мир!


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

Задача


Что же делать в таком случае? Кажется возможным не связываться с такими проектами, но не всегда это возможно. Поставим задачу сделать облачную обработку изображений, в частности — ресайз. В рамках одного из условий задачи поставим необходимым ограничения в использовании процессорного времени и установленных графических библиотек на стороне клиента.

Решение


Около года назад у меня возникла необходимость в реалтайм генерации небольших превьюшек картинок фотогалереи на сайте одного образовательного учреждения. В рамках доступной возможности сохранения конфиденциальности не буду упоминать название этого заведения. Так вот, изображения загружаются из админ.панели, и в силу определенной специфики деятельности людей, занимающихся администрированием сайта, не предоставляется возможным принудить их менять размер картинок хотя бы до приемлемого минимума. Т.о. на входе мы имеем картинки размером до 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:
image

Используя наше решение, мы можем сделать его ресайз, чтобы вписать изображение в область размером 200x200, используя следующий урл:
http://thumber.io/get/200x200/https://habrastorage.org/getpro/habr/comment_images/f22/27f/7d8/f2227f7d86053a207ebc88ae3377af4f.jpg

Результат обработки:
image

Думаю, интуитивно понятно, каким образом можно пользоваться обработкой подобного рода. В качестве параметра после /get/ можно использовать также процентное изменение. Например,
https://habrastorage.org/getpro/habr/post_images/1be/525/a7a/1be525a7a940f9e63705ffb1d4d9845e.jpg

Результат:
image


Гипотетически, возможно использование любого параметра ключа ­-resize утилиты convert. Более подробное описание использования возможностей мы разместили в небольшом документе, доступном по адресу http://thumber.io/Thumber.io.Documentation.pdf. Надеюсь, у желающих ознакомиться нет проблем с английским языком, и все будет понятно. Если что-то может требовать дополнительного пояснения, прошу задавать вопросы в комментарии.

Заключение


Прошел практически год с момента публикации данного решения. За это время были реальные примеры его использования в продакшне. Сейчас стоит вопрос в целесообразности плотной работы над данным направлением, его развитием, добавлением новых интересных фич, возможностей. Этот небольшой пост написан с целью сделать ресерч. Хабрасообщество, помогите принять решение. Есть ли у вас какие-нибудь мысли по поводу дальнейшего развития данного продукта и его прикладного использования?
Стоит ли работать над данным сервисом? Как по-вашему, может ли он быть полезным широкой аудитории?

Проголосовало 223 человека. Воздержалось 106 человек.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Комментарии (28)


  1. Delphinum
    23.01.2016 02:17
    +5

    Необходимость подобных сервисов напрямую зависит от их доступности. Лично для меня сервис будет представлять интерес только в случае его бесплатности (во всех отношениях) и постоянной доступности. Многим еще захочется создать свою локальную копию. Идея вполне годная и нужная.


    1. AdaStreamer
      23.01.2016 02:19

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


      1. Delphinum
        23.01.2016 02:24
        +1

        Никто не ведет речь о какой-либо оплате

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


        1. AdaStreamer
          23.01.2016 02:31

          Соглашусь. В большинстве случаев подобные сервисы работают по схеме «Больше обращений — больше стоимость». Как пример могу привести prerender.io. Но тут тоже есть определенный смысл — больше обращений означает востребованность исходного ресурса. Большая востребованность означает возможность получения выгоды (если это не благотворительная деятельность), что допускает возможные расходы, пусть и минимальные, на одну из компонент своей инфраструктуры.


          1. Delphinum
            23.01.2016 02:33

            Значит вам нужно задуматься о бесплатных лицензиях для клиентов, занимающихся благотворительной деятельностью )


  1. vshemarov
    23.01.2016 06:47
    +4

    Вот аналогичный сервис: uploadcare.com

    Но у вас проще использовать, т.к. не требуется регистрироваться, заливать картинку, а потом ее тягать, достаточно просто подставить в УРЛ. Но в этом направлении, кстати, можно подумать с точки зрения монетизации: для использования так, как есть, оставить сервис бесплатным. Но предусмотреть и регистрацию юзеров, введя дополнительные фишки для них, и это уже сделать платным.

    Как вариант: при бесплатном использовании хранить изображения в течение ограниченного времени (напр., месяц). Даже это будет большой плюс для тех, кто не хочет заморачиваться с ресайзом — прогнал картинку через ваш сервис при загрузке и сохранил у себя. А для платных хранить уже «вечно». В любом случае, если у сервиса будет расти популярность, то думать о монетизации придется, т.к. рано или поздно громадное хранилище картинок начнет требовать ощутимых ресурсов.


  1. vshemarov
    23.01.2016 06:49

    Да, и если на широкую публику, то, конечно же, нужен https


    1. AdaStreamer
      23.01.2016 14:06

      Согласен. Будет сделано.


  1. spmbt
    23.01.2016 14:12
    +1

    Авторы, если не подошло это по причине онлайновости, image+resize+online, то почему сами предлагаете онлайн-сервис, без исходников? И чем не устроил Gimp + nginx?
    >если… на своих серверах, доступа к которым нет ни у кого


    1. AdaStreamer
      23.01.2016 14:19

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


      1. spmbt
        23.01.2016 18:06
        +1

        > задача необходимости создания
        ---другими словами, осознать, что нужно создание обработчика? Я же показал ссылку на Гугл, где то же самое делается в массе других решений. Т.е. осознать есть с помощью чего, а написать несложно. Так что ваш проект не решает уникальной задачи.


        1. AdaStreamer
          23.01.2016 18:14

          Вы показали ссылку на Гугл, где в выдаче находятся ресурсы, позволяющее сделать ресайз, загрузив изображение вручную или указав ссылку на него. Такой подход можно использовать только если эти действия делать вручную. Мы же ставим задачу реализации такого сервиса в виде АПИ, где само использование может быть автоматизировано.


  1. 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 пишет временные файлы при расжатии.

    Ну и, простейшим скриптом с перебором можно замусорить ваше хранилище достаточно быстро.


    1. AdaStreamer
      23.01.2016 14:21

      Спасибо, на данном этапе мы надеялись на благоразумное использование. Если мы будем отправляться в большое плавание, косяки подобного рода обязательно будут устранены.


  1. Mithgol
    23.01.2016 15:00
    +2

    Можно сделать это решение строго джаваскриптовым, если от ImageMagick отказаться в пользу JIMP.

    Будет меньше накладных расходов на запуск внешнего (по отношению к Node.js) процесса, но чуть меньше производительность перекодировщика (JavaScript медленнее Си).


    1. AdaStreamer
      23.01.2016 15:07

      В этом случае на клиент (в браузер) предварительно будет загружено исходное изображение. Если это 20 изображений по 5МБ, это существенно увеличит траффик.


      1. Delphinum
        23.01.2016 15:09
        +1

        Вы ошибаетесь. Вам предлагают заменить ваш серверный кропольщик с Сишного на JSшный, только и всего.


    1. AdaStreamer
      23.01.2016 15:10
      +1

      Пардон, не сразу понял о чем вы


  1. gene4000
    23.01.2016 18:01
    +1

    Очень и очень полезная нужная вещь. Даже платно (если недорого:) можно использовать. Только тогда нужно будет добавить возможность заливки, без использования промежуточного сервера для хранения.


    1. AdaStreamer
      23.01.2016 18:06

      Спасибо. Внесем в список функционала возможность ручной заливки.


      1. gene4000
        23.01.2016 18:08

        Гм. Может быть мы слово «ручное» по-разному понимаем, но я говорил о каком-то api, например асинхронно на js что-то отправляется, а в ответ ссылка на файл приходит. А может через серверный скрипт, на php засылается. Я думаю, вы имели ввиду именно такой вариант, просто на всякий случай.


        1. AdaStreamer
          23.01.2016 18:09

          Да, в виде АПИ и планируется реализовать.


  1. Evgeny42
    23.01.2016 19:12
    +1

    Можно подумать еще над кропом. Например передавать соотношение сторон (ratio), или сами размеры, и если приспичит, то и позицию кропа. Включая как пиксели так и ключи, типа тех что есть у backgroud-position.

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

    В общем можно много чего придумать, и все это довольно легко.


  1. funca
    23.01.2016 20:43
    +2

    Из софта есть еще опенсорсный thumbor.org — там REST API, умный кроп детекторами фич и физиономий через OpenCV, хранение на s3, дружелюбие к CDN и масштабируемость, опционально аплоад. Есть несколько рецептов для docker-compose, с помощью которых можно развернуть подходящую конфигурацию в облаке за полчаса.
    Интересность вашего решения как сервиса зависит от SLA.


  1. vladimirkolyada
    25.01.2016 11:05
    +1

    https://cdn.thisislogic.ru наше детище. Используетя в продакш, не только ETag но и LastModified:) Хранится все… о боги в кластере Redis:) Доступность на данный момент простая, 2 канала и round robin. Проверяет изменение картинки на вашем сервисе в соответствии с правилом Last + опытным путем подобранным интервалом (что-то около 15 минут). Как пользоваться — все на странице написано.


    1. AdaStreamer
      25.01.2016 12:17

      image


    1. AdaStreamer
      25.01.2016 12:18

      А CDN — это действительно CDN? В каких регионах у вас датацентры?


      1. vladimirkolyada
        25.01.2016 13:04

        Есть такое на сафари и старых андроидах. Связано с тем, что они не умеют работать с несколькими сертификатами в пределах одного ip. Надо или выделять ip или ставить default сертификат с именем, которое надо поддерживать. Я хочу выделить ip, как отдельно появится возможность. По поводу датацентров — это сильно сказано. Это всего лишь 2 HP DL360 сервера:) Центральный регион, но не москва. Пока нет возможности расширяться, ведь проект некоммерческий. Простенькое тестирование можно запустить с LoadImpact, получить соответствующие выводы о приемлемости — доступности — скорости.