Сегодня поговорим о том как проще всего воткнуть водяной знак на картинки в Битрикс. Например, на все изображения каталога.
Полной автоматики получить не удалось, хотя есть зацепки, но об этом ниже.
Итак, за основу я взял метод ResizeImageGet. Почему? Потому что именно он делает копию картинки, а не воздействует на оригинал. И именно он внутри себя обращается к методу CFile::ResizeImageFile, который уже может наложить водяной знак.
Для начала создаем класс с одним статическим методом:
иначе, значение может быть repeat, тогда размер не меняется и производится заполнение всего изображения ватемарком
Собственно, это и будет ваш класс для применения вотермарка. В нем указаны настройки, которыми можно крутить для знака.
Затем идем в /bitrix/modules/main/classes/general/file.php и находим там метод ResizeImageGet. Копируем его как есть и вставляем в ваш метод. Я намеренно не прикладываю здесь готовых файлов, потому что данный метод может довольно часто меняться, и через пару версий уже быть совершенно иным.
Вставили метод, теперь работаем с ВАШИМ классом, в ядре ничего не меняем. Сразу скажу, что вы можете менять его как угодно, какие угодно параметры добавлять, но я шел по пути минимального вмешательства.
Первое, находим блок проверки размерности картинки и либо удаляем его, либо комментим. Это сделать надо для того, чтобы вы могли натравливать метод ресайза без изменения фактических размеров картинки (но вместе с тем сделав копию картинки, чтобы не повредить оригинал).
Затем находим еще блок кода непосредственно перед ресайзом копии.
А где вторым прямоугольником отмечено, мы заменяем array() на ваш новый массив. Это и есть применение вотермарка и собственно все танцы с бубном ради него. И вот теперь об автоматике. Если вы взглянете в коде еще выше, то увидите там обработку события OnBeforeResizeImage. И вот его можно научить принимать переменные по ссылке, и дополнить его передачей параметра вотермарка. Тогда все это можно было бы менять в обработчике. Очень маленькая мелочь, и я надеюсь ее Битрикс сделает рано или поздно.
По сути все, теперь как применять. Ну во-первых, если у вас уже используется ResizeImageGet, вы можете просто заменить в коде вызов CFile::ResizeImageGet на CFileWater::ResizeImageGet и все будет работать.
Теперь о том, почему я настройки знака вынес в отдельную переменную. А чтобы для разных вариантов подбрасывать разные водяные знаки.
Например:
Спасибо, интересно!
У меня правда первая мысль была обратиться к одному из обработчиков OnAfterResizeImage/OnBeforeResizeImage, но нужно проверить. Не рассматривали этот подход? Почему отказались? Из-за лишней операции перезаписи или эти события не сработают при нормальных размерах картинки, т.е. без фактического ресайза?
Да-да, но я про визивиг, вы кнопку свою в визивиг добавляли? Там же <pre><code class="php"> вставлять надо или вроде такого...
Или всё в режиме html пишете?
При таком подходе (если применять наложение ко всем изображениям элемента) в том случае, когда в инфоблоке 20 тыс. элементов и у каждого по 10 фото, вашему жесткому диску я не сильно позавидую...
Ресайзить и наносить ватермарки надо только в момент создания элементов, а не потом, при выводе на странице. Мы так делали — заливали номенклатуру товаров из 1С, а потом ресайзили "налету", как результат 50Гиговая папка с сайтом...
Не, зерно правды в ваших словах есть, просто большинству сайтов не надо париться с дублями картинок - их не так много.
Для большого проекта ваш путь вернее само собой. Только я оригиналы все равно сохранял бы, хотя бы постингов на какой-нить свой фтп, пусть лежат.
Тут по сути вопрос стоит "нужно ли вам сохранять оригиналы изображений?", отресайзенные до веб-размеров, много гигабайт не займу (иначе просто жаль посетителей).
Кому нужно (например чтобы спустя время без перезаливки всего - под ретину подстроиться) - то вариант с сохранением оригиналов - очень даже очень. Да и об импорте тут речи нет.
Годный вариант.
Ребята не понятно к чему пристали в комментариях - вам показали способ, как решить конкретную задачу. Это же не руководство, как надо делать на любом проекте. Хотите храните оригиналы, хотите не храните. Все просто
Никак не пойму, чем стандартный вотермарк не угодил? Только если на момент публикации статьи его не было, хотя, насколько я помню, это не так.
И зачем комментировать строки, если при наличии фильтра(а вотермарка, как раз оно и есть) он всё равно его применит?
Леонид, ключевое - "на лету", то есть оригинал не страдает, и не надо перегенерировать каталог. Если какой-то такой же штатный функционал есть (я не про сам вотермарк), то раньше его точно не было.
Вотермарки вроде появились в ResizeImageGet ещё в 11 версии битрикса. (да что там, вы сами используете этот функционал, учитывая копирование практически без изменений этого самого метода)
И ваш код:
Да, вызов получается подлиннее. Зато не надо создавать свой класс, не надо ничего копировать из ядра. И всё так же работает "на лету", оригинал не страдает.
К сожалению, не могу проверить было ли всё так, на момент написания статьи, самая старая версия битрикса у меня на руках 14.5, от 6.12.16. А там уже всё работает, как и сейчас. А именно вот так:
Аааааа такое адище расказано
я почти уверен что даже в битриксе есть правильные пути, этот путь вообще на уровне "я закончил универ, я прафесианальный кодир"
У меня правда первая мысль была обратиться к одному из обработчиков OnAfterResizeImage/OnBeforeResizeImage, но нужно проверить. Не рассматривали этот подход? Почему отказались? Из-за лишней операции перезаписи или эти события не сработают при нормальных размерах картинки, т.е. без фактического ресайза?
Или всё в режиме html пишете?
Редактор не трогал. Сапожник без сапог
Ресайзить и наносить ватермарки надо только в момент создания элементов, а не потом, при выводе на странице.
Модераторы 1С еще имеют обыкновение добавлять к товарам фото по несколько Мб каждая и все это с импортом вы предлагаете влить на сайт?
Дело Ваше, но я бы так не делал) А ссылка, чтобы не представляться (и в то же время может кому то будет интересно, кто у Долганина в посте "умничает")
Для большого проекта ваш путь вернее само собой. Только я оригиналы все равно сохранял бы, хотя бы постингов на какой-нить свой фтп, пусть лежат.
А в целом я вообще против водяных знаков.
Кому нужно (например чтобы спустя время без перезаливки всего - под ретину подстроиться) - то вариант с сохранением оригиналов - очень даже очень. Да и об импорте тут речи нет.
Ребята не понятно к чему пристали в комментариях - вам показали способ, как решить конкретную задачу. Это же не руководство, как надо делать на любом проекте. Хотите храните оригиналы, хотите не храните. Все просто
И зачем комментировать строки, если при наличии фильтра(а вотермарка, как раз оно и есть) он всё равно его применит?
И ваш код:
Можно было бы заменить на:
Да, вызов получается подлиннее. Зато не надо создавать свой класс, не надо ничего копировать из ядра. И всё так же работает "на лету", оригинал не страдает.
К сожалению, не могу проверить было ли всё так, на момент написания статьи, самая старая версия битрикса у меня на руках 14.5, от 6.12.16. А там уже всё работает, как и сейчас. А именно вот так:
я почти уверен что даже в битриксе есть правильные пути, этот путь вообще на уровне "я закончил универ, я прафесианальный кодир"