Настройка автоматического наложения водяных знаков 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка автоматического наложения водяных знаков 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1181
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    813
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Настройка автоматического наложения водяных знаков 1С-Битрикс

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

Точки перехвата при загрузке изображений

В Битрикс файлы загружаются через CFile::SaveFile() и CFile::Add(). Событие OnBeforeFileAdd позволяет перехватить загрузку до сохранения на диск:

AddEventHandler('main', 'OnBeforeFileAdd', function(&$fileFields, $moduleId) {
    // $moduleId: 'iblock', 'sale', 'catalog' и т.д.
    if ($moduleId !== 'iblock') {
        return; // Обрабатываем только изображения каталога
    }

    $mimeType = $fileFields['type'] ?? '';
    if (!str_starts_with($mimeType, 'image/')) {
        return;
    }

    $tmpFile = $fileFields['tmp_name'];
    applyWatermarkInPlace($tmpFile);
});

Функция applyWatermarkInPlace модифицирует временный файл до его сохранения в /upload/. Это означает: в базе и на диске окажется уже обработанный файл, без необходимости хранить оригинал и кеш отдельно.

Различие между изменением и новой загрузкой

Событие OnBeforeFileAdd срабатывает только при новых загрузках. При обновлении элемента каталога, если изображение не менялось, файл не перезаписывается — событие не сработает. Это корректное поведение.

Проблема: если администратор загружает изображение через массовый импорт CSV или через REST API (iblock.element.update), событие OnBeforeFileAdd также должно срабатывать — и срабатывает, так как импорт в итоге вызывает CFile::SaveFile().

Исключения из автоматического наложения

Не все изображения нужно маркировать. Логотип компании в шапке, иконки категорий, системные изображения — всё это проходит через CFile. Фильтрация по $moduleId решает только часть задачи.

Для более точного управления добавляем проверку контекста через сессионную переменную:

AddEventHandler('main', 'OnBeforeFileAdd', function(&$fileFields, $moduleId) {
    if ($moduleId !== 'iblock') return;
    if (!isset($_SESSION['WATERMARK_ENABLED'])) return;

    $iblockId = $_SESSION['CURRENT_IBLOCK_ID'] ?? null;
    $noWatermarkIblocks = \Bitrix\Main\Config\Option::get('catalog', 'no_watermark_iblocks', '');
    $excluded = array_map('intval', explode(',', $noWatermarkIblocks));

    if ($iblockId && in_array($iblockId, $excluded)) return;

    applyWatermarkInPlace($fileFields['tmp_name']);
});

Переменная CURRENT_IBLOCK_ID устанавливается в обработчике события OnBeforeIBlockElementAdd / OnBeforeIBlockElementUpdate. Список исключённых инфоблоков хранится в b_option.

Обработка ошибок при наложении

Если GD-обработка завершится с ошибкой (битый файл, неподдерживаемый формат), загрузка не должна блокироваться. Обёртка applyWatermarkInPlace в блоке try/catch — при ошибке файл сохраняется без водяного знака, ошибка пишется в лог:

function applyWatermarkInPlace(string $tmpFile): void
{
    try {
        // Обработка через GD
        $result = processWatermark($tmpFile);
        if ($result) {
            file_put_contents($tmpFile, $result);
        }
    } catch (\Throwable $e) {
        \Bitrix\Main\Diag\Debug::writeToFile(
            $e->getMessage(), 'watermark_error', '/bitrix/watermark.log'
        );
        // Не прерываем загрузку — файл сохранится оригинальным
    }
}

Производительность при массовой загрузке

При импорте каталога 5 000 товаров с 3 изображениями каждый — 15 000 операций GD. На среднем сервере обработка одного изображения занимает 50–150 мс. Итого: 12–37 минут добавляется ко времени импорта. Если это неприемлемо — переключаемся на асинхронную схему: сохраняем оригинал, ставим задачу в очередь b_agent, агент обрабатывает батчами по 100 изображений.

Что настраиваем

  • Обработчик события OnBeforeFileAdd с фильтрацией по $moduleId
  • Список инфоблоков-исключений в b_option
  • Обработку ошибок GD без блокировки загрузки
  • Для массового импорта: асинхронную обработку через агент
  • Мониторинг лога /bitrix/watermark.log на предмет битых изображений