Добро пожаловать на сайт <БагБД>, где вы можете задавать вопросы о программировании и разработке на Битрикс и Битрикс24, и получать быстрые и квалифицированные ответы от профессионалов!

Еще раз про наложение водяного знака

00 голосов
4
Уже сто раз про это писали. В гугле я все это нашел, но осталось несколько вопросов. Свою ситуацию не встретил.

К делу...
Есть инфоблок. В нем есть несколько полей с файлами. Поля множественного типа.
Добавляем в них картинки и нужно на эти картинки ставить водяной знак.

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

Лезем в init.php и там пишем:
Код
AddEventHandler("iblock", "OnBeforeIBlockElementAdd", "AddWatermarkToWallpaper");
AddEventHandler("iblock", "OnBeforeIBlockElementUpdate", "AddWatermarkToWallpaper");

И сама функция:
Код
function AddWatermarkToWallpaper(&$arFields){
   $wallpaperArray = Array(12); //Список блоков с обоями. А вдруг их будет больше?
   if (in_array($arFields['IBLOCK_ID'], $wallpaperArray)){
      $tmp = Array();
      foreach($arFields['PROPERTY_VALUES'] as $key => $value) //получаем список свойств (разные разрешения)
         foreach($value as $key2 => $value2) //получаем список их значений
            if($value2["tmp_name"]) $tmp[] = $value2["tmp_name"];
      if($tmp[0]){
         //Что дальше?
      }
   }
}

На этом шаге у меня есть массив, в который записаны все картинки, которые добавили или изменили.
Что-то типа tmp/f4F514FX. Внимание, вопрос: как применить функцию CFile::ResizeImageGet зная только путь временной картинки и как потом заменить ее на картинку с водяным знаком?

Конечно, я пробовал подставить (значения только для теста):
Код
$v = CFile::ResizeImageGet($tmp[0], array('width'=>150, 'height'=>150), BX_RESIZE_IMAGE_PROPORTIONAL, true);

Но это, очевидно, не работает (да и не должно, судя по документации).
Мне кажется верным шагом смотреть в сторону CFile::SaveFile, но не совсем ясна работа функции. Не будет ли у меня дублирование файлов, куда переносится файл?
Пожалуйста, помогите разобраться и найти верное решение задачи.
спросил 19 Дек, 13 от maxdj (480 баллов)

4 Ответы

00 голосов
Цитата
scifi пишет:
Внимание, вопрос: как применить функцию CFile::ResizeImageGet зная только путь временной картинки и как потом заменить ее на картинку с водяным знаком?

Код
 CFile::ResizeImageGet(CFile::MakeFileArray($tmp[0]), array('width'=>150, 'height'=>150), BX_RESIZE_IMAGE_PROPORTIONAL, true);
ответил 04 Март, 14 от Arn4 (2,140 баллов)
00 голосов
Это решение не работает, функция ничего не возвращает и размер картинки не меняется.
Кстати, использовать функцию MakeFileArray в таком случае нет смысла, т.к. я уже получаю такую массив при чтении свойств:
Код
      $tmp = Array();
      foreach($arFields['PROPERTY_VALUES'] as $key => $value)
         foreach($value as $key2 => $value2)
            if($value2["tmp_name"]) $tmp[] = $value2; //вот тут теперь будет та же структура, что и после MakeFileArray         
      if($tmp[0]){ //это просто для отладки тут так сделано
         $v = CFile::ResizeImageGet($tmp[0], array('width'=>150, 'height'=>150), BX_RESIZE_IMAGE_PROPORTIONAL, true);
         //$v = CFile::ResizeImageGet(CFile::MakeFileArray($tmp[0]), array('width'=>150, 'height'=>150), BX_RESIZE_IMAGE_PROPORTIONAL, true);
         file_put_contents($_SERVER['DOCUMENT_ROOT']."/log.txt", print_r($v, true));
      }


Не работают и первый вариант, и закомментированный.
ответил 24 Июнь, 14 от maxdj (480 баллов)
00 голосов
Это было очень веселое и познавательное приключение. Сражение с АПИ битрикса, кровь, кишки, расчлененка. Уберите детей от экранов.

Сначала весь код:
Код
function AddWatermarkToWallpaper(&$arFields){
   $wallpaperArray = Array(12); //Список блоков с обоями. А вдруг их будет больше?
   if (in_array($arFields['IBLOCK_ID'], $wallpaperArray)){
   
      $arFilter_WM = Array(
         array("name" => "watermark", 
         "position" => "br", 
         "size"=>"real", 
         "alpha_level"=>"30",
         "file"=>$_SERVER['DOCUMENT_ROOT']."/bitrix/templates/games/images/logo_t.png")
      );   
      
      $tmp = Array();
      foreach($arFields['PROPERTY_VALUES'] as $key => $value)
         foreach($value as $key2 => $value2)
            if($value2["tmp_name"]){
               $v = CFile::SaveFile(CFile::MakeFileArray($value2["tmp_name"]), "abc");
               //тупак битрикса
               $arSizeORIG = getimagesize($_SERVER['DOCUMENT_ROOT'].CFile::GetPath($v));
               $widthBIG =  intval($arSizeORIG[0])-1;
               $heightBIG =  intval($arSizeORIG[0])-1;
               //конец тупака битрикса
               $v = CFile::ResizeImageGet($v, Array('width' => $widthBIG, 'height' => $heightBIG), BX_RESIZE_IMAGE_PROPORTIONAL, false, $arFilter_WM);
               $arFields['PROPERTY_VALUES'][$key][$key2] = CFile::MakeFileArray($v["src"]);               
            }
   }
}


Особенно интересно это место:
Код
               $arSizeORIG = getimagesize($_SERVER['DOCUMENT_ROOT'].CFile::GetPath($v));
               $widthBIG =  intval($arSizeORIG[0])-1;
               $heightBIG =  intval($arSizeORIG[0])-1;
               $v = CFile::ResizeImageGet($v, Array('width' => $widthBIG, 'height' => $heightBIG), BX_RESIZE_IMAGE_PROPORTIONAL, false, $arFilter_WM);


Зачем я меняю размер картинки на 1 px?
Все очень просто: функция не добавит водяной знак, если вы не поменяете размер. Просто супер. Пожалуй, эта функция пока занимает первое место в рейтинге тупак года от битрикс.
ответил 24 Окт, 14 от maxdj (480 баллов)
00 голосов
ахаха, вот это изврат! использую phpThumb и никакого колдовства
ответил 23 Фев, 15 от HolyRage (280 баллов)

Похожие вопросы

0 голосов
3 ответов
спросил 14 Окт, 13 от Manakus (160 баллов)
0 голосов
7 ответов
спросил 27 Июль, 13 от Kania (5,180 баллов)
0 голосов
7 ответов
0 голосов
8 ответов
спросил 20 Июнь, 13 от Fierce88 (440 баллов)
0 голосов
5 ответов