Следи за нами

Создание страниц для брошюры о товарах

Дата создания: г.

Как с помощью класса Imagick было создано изображение с основной фотографией товара и наложенных на данной фотографии основных характеристиках товара?

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

Для формирования изображения был выбран php-класс Imagick.

Весь процесс разбивается на несколько этапов:

Подготовительный этап

Для начала выводим менеджеру форму с опциональными полями: инфоблок, тип цены, параметры результирующего изображения

Дальше, нужно написать скрипт, который будет перебирать все товары из каталога. Для этого, нужно по нажатию на кнопку запуска обработчика, произвести первый запрос к базе данных с учетом разбиения выборки постранично (количество единовременно загружаемых товаров соответствует возможностям сервера. Моя реализация построена исходя из предположения о том, что за один шаг обрабатывается один товар), а затем - уже настроить пошаговую обработку всех товаров.

Обработчик на языке JavaScript выглядит примерно так:

var maxRows = false; var Form; $(document).on('click','button#broshureStart',function () { Form = $(this).parents('form'); var num = 1; var wait = BX.showWait('loading'); var persentsContainer = Form.find('p.persents'); function work_with_row(num, d){ var Persents = (parseInt(num))*100 / parseInt(maxRows); persentsContainer.find('span.pv').html(Math.round(Persents)); persentsContainer.find('span.rv').html(parseInt(num)); $.ajax({ type: "POST", url: location.href, data: {num: num, action: 'createProducts',sessid: Form.find('input[name="sessid"]').val() }, dataType: "json", success: function (data) { d &amp;&amp; d.resolve(); }, onfailure: function(){ d &amp;&amp; d.resolve(); } }); } $.ajax({ type: "POST", url: location.href, data: {num: num, action: 'createProducts',sessid: Form.find('input[name="sessid"]').val() }, dataType: "json" }).then(function (data) { if(!maxRows &amp;&amp; data.CNT!==undefined){ maxRows = data.CNT; var deferreds = []; var i=10; persentsContainer.find('span.maxrows').html(maxRows); persentsContainer.show(); for(var index = num+1; index <p>Таким образом, будут отправлены запросы для обработки всех товаров в каталоге.</p> <a name="1"></a><h2>Скрипт обработки ajax-запроса</h2> <p>Для обработки запросов на этой же странице в самом начале добавляем обработчик ajax-запросов:</p> <pre class="brush: js">$POST_RIGHT = $APPLICATION-&gt;GetGroupRight("catalog"); // если нет прав - отправим к форме авторизации с сообщением об ошибке if ($POST_RIGHT == "D") $APPLICATION-&gt;AuthForm(GetMessage("ACCESS_DENIED")); $context = Application::getInstance()-&gt;getContext(); $request = $context-&gt;getRequest(); if ($request-&gt;isPost() &amp;&amp; $request-&gt;get('action') &amp;&amp; $POST_RIGHT == "W" &amp;&amp; check_bitrix_sessid()) { $arResult = array(); $arPostData = $request-&gt;getPostList()-&gt;toArray(); if($request-&gt;get('action')=='createProducts'){ $pageNum = $request-&gt;get('num'); if(intval($pageNum)setNPage($pageNum); $processor-&gt;GetIblockElementData(); $arResult = $processor-&gt;ProcessElementData(); $arResult['CNT'] = $processor-&gt;ReturnElementsCnt(); $arResult['CNT'] = $processor-&gt;ReturnElementsCnt(); if($request-&gt;isAjaxRequest()){ $APPLICATION-&gt;RestartBuffer(); header('Content-type: application/json'); echo \Bitrix\Main\Web\Json::encode($arResult); exit(); } } </pre> <p>Таким образом, при первом запросе к серверу будет получено общее количество элементов инфоблока и можно будет запустить пошаговый обработчик всех товаров.</p> <a name="2"></a><h2>Создание изображения с информацией о товаре</h2> <p>Сам обработчик товаров представляет собой класс с основными методами. Рассмотрим их:</p> <a name="3"></a><h3>Выборка товаров из каталога</h3> <pre class="brush: js">protected function GetIblockElementItems( $arParams = array('filter' =&gt; array(), 'select' =&gt; false, 'sort' =&gt; array('name' =&gt; 'asc'), 'page_params' =&gt; false, 'group' =&gt; false), $life_time = 3600) { if (!isset($arParams['filter']) || empty($arParams['filter'])) return false; $arFilter = $arParams['filter']; $arSelect = (isset($arParams['select'])) ? $arParams['select'] : false; $arSort = (isset($arParams['sort'])) ? $arParams['sort'] : array('name' =&gt; 'asc'); $pageParams = (isset($arParams['page_params'])) ? $arParams['page_params'] : false; $groupParams = (isset($arParams['group'])) ? $arParams['group'] : false; $return = false; $cache_params = array(); foreach (array_keys($arParams) as $array_key) { if (is_array($arParams[$array_key])) { foreach ($arParams[$array_key] as $key =&gt; $value) { $cache_params[$array_key . '-' . $key] = $value; } } elseif (is_bool($arParams[$array_key])) { $cache_params[$array_key] = $arParams[$array_key] ? 1 : 0; } } $cache_id = md5(serialize($cache_params)); $cache_dir = __CLASS__ . '/' . __FUNCTION__; $cache = \Bitrix\Main\Data\Cache::createInstance(); if ($life_time clean($cache_id, $cache_dir); } if ($cache-&gt;initCache($life_time, $cache_id, $cache_dir)) { $return = $cache-&gt;getVars(); } elseif ($cache-&gt;startDataCache() &amp;&amp; \Bitrix\Main\Loader::includeModule('iblock')) { if( is_array($arSelect) &amp;&amp; in_array('IBLOCK_ID',$arSelect) &amp;&amp; in_array('ID',$arSelect) ){ $filterProperties = array(); $filterFields = array(); foreach ($arSelect as $select) { if(strpos($select,'PROPERTY_')!==false){ $filterProperties[] = str_replace('PROPERTY_','',$select); } else { $filterFields[] = $select; } } $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $filterFields); while ($arElement = $rsItems-&gt;GetNextElement()) { $arFields = $arElement-&gt;GetFields(); if(!empty($filterProperties)){ foreach ($filterProperties as $arFilterCode){ if(!isset($arFields['PROPERTIES'])) $arFields['PROPERTIES'] = array(); $arFields['PROPERTIES'] = array_merge($arFields['PROPERTIES'],$arElement-&gt;GetProperties(false,array( 'CODE'=&gt;$arFilterCode ))); // $arFields['PROPERTIES'][$arFilterCode] = ; } // $arFields['PROPERTIES'] = $arElement-&gt;GetProperties(false,array('CODE'=&gt;$filterProperties)); } $return[] = $arFields; } } elseif (empty($arSelect)){ $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $arSelect); while ($arElement = $rsItems-&gt;GetNextElement()) { $arFields = $arElement-&gt;GetFields(); $arFields['PROPERTIES'] = $arElement-&gt;GetProperties(); $return[] = $arFields; } } else { $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $arSelect); while ($arElement = $rsItems-&gt;GetNext()) { $return[] = $arElement; } } if (!empty($return)) { foreach ($return as $key =&gt; $arItem) { if (!empty($arItem['PROPERTIES'])) { foreach ($arItem['PROPERTIES'] as $pCode =&gt; $arProperty) { $return[$key]['PROPERTIES'][$pCode] = \CIBlockFormatProperties::GetDisplayValue( array('ID' =&gt; $arItem['ID'], 'NAME' =&gt; $arItem['NAME']), $arProperty, ''); } } } } if(isset($pageParams) &amp;&amp; !empty($pageParams) &amp;&amp; $pageParams['nPageSize']==1 &amp;&amp; !empty($return[0])){ $return = $return[0]; } $return = array( 'ITEMS'=&gt;$return, 'MAX_CNT'=&gt;$rsItems-&gt;NavPageCount ); $cache-&gt;endDataCache($return); } $this-&gt;settings['ELEMENTS_CNT'] = $return['MAX_CNT']; return $return['ITEMS']; }</pre> <a name="4"></a><h3>Получение информации об одном товаре</h3> <pre class="brush: js">protected function GetIblockElementItems( $arParams = array('filter' =&gt; array(), 'select' =&gt; false, 'sort' =&gt; array('name' =&gt; 'asc'), 'page_params' =&gt; false, 'group' =&gt; false), $life_time = 3600) { if (!isset($arParams['filter']) || empty($arParams['filter'])) return false; $arFilter = $arParams['filter']; $arSelect = (isset($arParams['select'])) ? $arParams['select'] : false; $arSort = (isset($arParams['sort'])) ? $arParams['sort'] : array('name' =&gt; 'asc'); $pageParams = (isset($arParams['page_params'])) ? $arParams['page_params'] : false; $groupParams = (isset($arParams['group'])) ? $arParams['group'] : false; $return = false; $cache_params = array(); foreach (array_keys($arParams) as $array_key) { if (is_array($arParams[$array_key])) { foreach ($arParams[$array_key] as $key =&gt; $value) { $cache_params[$array_key . '-' . $key] = $value; } } elseif (is_bool($arParams[$array_key])) { $cache_params[$array_key] = $arParams[$array_key] ? 1 : 0; } } $cache_id = md5(serialize($cache_params)); $cache_dir = __CLASS__ . '/' . __FUNCTION__; $cache = \Bitrix\Main\Data\Cache::createInstance(); if ($life_time clean($cache_id, $cache_dir); } if ($cache-&gt;initCache($life_time, $cache_id, $cache_dir)) { $return = $cache-&gt;getVars(); } elseif ($cache-&gt;startDataCache() &amp;&amp; \Bitrix\Main\Loader::includeModule('iblock')) { if( is_array($arSelect) &amp;&amp; in_array('IBLOCK_ID',$arSelect) &amp;&amp; in_array('ID',$arSelect) ){ $filterProperties = array(); $filterFields = array(); foreach ($arSelect as $select) { if(strpos($select,'PROPERTY_')!==false){ $filterProperties[] = str_replace('PROPERTY_','',$select); } else { $filterFields[] = $select; } } $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $filterFields); while ($arElement = $rsItems-&gt;GetNextElement()) { $arFields = $arElement-&gt;GetFields(); if(!empty($filterProperties)){ foreach ($filterProperties as $arFilterCode){ if(!isset($arFields['PROPERTIES'])) $arFields['PROPERTIES'] = array(); $arFields['PROPERTIES'] = array_merge($arFields['PROPERTIES'],$arElement-&gt;GetProperties(false,array( 'CODE'=&gt;$arFilterCode ))); } } $return[] = $arFields; } } elseif (empty($arSelect)){ $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $arSelect); while ($arElement = $rsItems-&gt;GetNextElement()) { $arFields = $arElement-&gt;GetFields(); $arFields['PROPERTIES'] = $arElement-&gt;GetProperties(); $return[] = $arFields; } } else { $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $arSelect); while ($arElement = $rsItems-&gt;GetNext()) { $return[] = $arElement; } } if (!empty($return)) { foreach ($return as $key =&gt; $arItem) { if (!empty($arItem['PROPERTIES'])) { foreach ($arItem['PROPERTIES'] as $pCode =&gt; $arProperty) { $return[$key]['PROPERTIES'][$pCode] = \CIBlockFormatProperties::GetDisplayValue( array('ID' =&gt; $arItem['ID'], 'NAME' =&gt; $arItem['NAME']), $arProperty, ''); } } } } if(isset($pageParams) &amp;&amp; !empty($pageParams) &amp;&amp; $pageParams['nPageSize']==1 &amp;&amp; !empty($return[0])){ $return = $return[0]; } $return = array( 'ITEMS'=&gt;$return, 'MAX_CNT'=&gt;$rsItems-&gt;NavPageCount ); $cache-&gt;endDataCache($return); } $this-&gt;settings['ELEMENTS_CNT'] = $return['MAX_CNT']; return $return['ITEMS']; }</pre> <a name="5"></a><h3>Создание объекта IMagick</h3> <pre class="brush: js">protected function ReadImage(){ try{ $this-&gt;_Imagick = new \Imagick(); $this-&gt;_Imagick-&gt;readImage($this-&gt;_absPath); } catch (Exception $e) { \CAdminMessage::ShowMessage($e-&gt;getMessage()); die(); } }</pre> <a name="6"></a><h3>Создание результирующего изображения</h3> <pre class="brush: js">public function CreateResultImage($width,$height){ // для начала заменим размеры изображения $blur = max( $this-&gt;_Imagick-&gt;getImageWidth() / $width, $this-&gt;_Imagick-&gt;getImageHeight()/$height); if($blur!==1){ $this-&gt;_Imagick-&gt;resizeImage($width,$height,null,$blur); } }</pre> <a name="7"></a><h3>Создание миниатюр изображений в других цветах:</h3> <pre class="brush: js">public function AddSamplesToMasterPhoto($arImages,$sampleWidth){ $arThumbs = array(); $labels = array(); $this-&gt;imgWidthStart = $sampleWidth* .1; foreach ($arImages as $arImage) { $thumb = new \Imagick(Application::getDocumentRoot().$arImage['SRC']); $thumb-&gt;adaptiveResizeImage($sampleWidth*.9, 0); $arThumbs[] = $thumb; $labels[] = $this-&gt;DrawImageColor($arImage,$sampleWidth*.9); } $maxHeight = 0; $maxLabelHeight = 0; foreach ($arThumbs as $num =&gt; $imagick) { $imgHeight = $imagick-&gt;getImageHeight(); $maxHeight = max($maxHeight,$imgHeight); $maxLabelHeight = max($maxLabelHeight, $labels[$num]-&gt;getImageHeight()); } // местоположение семплов должно быть на треть их высоты от края $offsetY = $this-&gt;_Imagick-&gt;getImageHeight() - $maxHeight*2; $labelOffsetY = $offsetY + $maxHeight*1.1; $offsetX = $sampleWidth*.1; foreach ($arThumbs as $num=&gt;$imagick) { $this-&gt;_Imagick-&gt;compositeImage($imagick,\Imagick::COMPOSITE_OVER, $offsetX, $offsetY); $this-&gt;_Imagick-&gt;compositeImage($labels[$num],\Imagick::COMPOSITE_OVER, $offsetX, $labelOffsetY); $offsetX += $sampleWidth*1.05; } $this-&gt;imgLastPos = $offsetY; }</pre> <a name="8"></a><h3>Функция наложения текста на изображении</h3> <pre class="brush: js">protected function DrawText($text,$size,$color,$bg=false,$maxWidth = false){ $draw = new \ImagickDraw(); $draw-&gt;setFillColor($color); $draw-&gt;setFontSize($size); $metrics = $this-&gt;_Imagick-&gt;queryFontMetrics($draw, $text); $image = new \Imagick(); if($bg){ $image-&gt;newImage($metrics['textWidth'], $metrics['textHeight'], $bg); } else { $image-&gt;newImage($metrics['textWidth'], $metrics['textHeight'], new \ImagickPixel('transparent')); } $draw-&gt;annotation(0, $metrics['ascender'], $text); $image-&gt;drawImage($draw); if($maxWidth &amp;&amp; $metrics['textWidth'] &gt; $maxWidth){ $image-&gt;adaptiveResizeImage($maxWidth,0); } return $image; }</pre> <p>В данной функции кроме непосрдественного вывода текста на изображении, реализован механизм отрисовки фоновой подложки под изображением. Если цвет фона задан - будет выведен он.</p> <a name="9"></a><h3>Сохранение полученных результатов</h3> <pre class="brush: js">public function SaveResultImage($folder,$fileName){ if(!file_exists(Application::getDocumentRoot().$folder)){ mkdir(Application::getDocumentRoot().$folder); } $this-&gt;_Imagick-&gt;setImageFormat("jpg"); $this-&gt;_Imagick-&gt;writeImage(Application::getDocumentRoot().$folder.'/'.$fileName); }</pre> <p>Таким образом, в указанной менеджером папке на сайте будут размещены изображения с товарами и актуальной инфорвацией о товарах и их торговых предложениях.</p> <div style="clear:both"></div> <br>

Таким образом, будут отправлены запросы для обработки всех товаров в каталоге.

Скрипт обработки ajax-запроса

Для обработки запросов на этой же странице в самом начале добавляем обработчик ajax-запросов:

$POST_RIGHT = $APPLICATION-&gt;GetGroupRight("catalog"); // если нет прав - отправим к форме авторизации с сообщением об ошибке if ($POST_RIGHT == "D") $APPLICATION-&gt;AuthForm(GetMessage("ACCESS_DENIED")); $context = Application::getInstance()-&gt;getContext(); $request = $context-&gt;getRequest(); if ($request-&gt;isPost() &amp;&amp; $request-&gt;get('action') &amp;&amp; $POST_RIGHT == "W" &amp;&amp; check_bitrix_sessid()) { $arResult = array(); $arPostData = $request-&gt;getPostList()-&gt;toArray(); if($request-&gt;get('action')=='createProducts'){ $pageNum = $request-&gt;get('num'); if(intval($pageNum)setNPage($pageNum); $processor-&gt;GetIblockElementData(); $arResult = $processor-&gt;ProcessElementData(); $arResult['CNT'] = $processor-&gt;ReturnElementsCnt(); $arResult['CNT'] = $processor-&gt;ReturnElementsCnt(); if($request-&gt;isAjaxRequest()){ $APPLICATION-&gt;RestartBuffer(); header('Content-type: application/json'); echo \Bitrix\Main\Web\Json::encode($arResult); exit(); } }

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

Создание изображения с информацией о товаре

Сам обработчик товаров представляет собой класс с основными методами. Рассмотрим их:

Выборка товаров из каталога

protected function GetIblockElementItems( $arParams = array('filter' =&gt; array(), 'select' =&gt; false, 'sort' =&gt; array('name' =&gt; 'asc'), 'page_params' =&gt; false, 'group' =&gt; false), $life_time = 3600) { if (!isset($arParams['filter']) || empty($arParams['filter'])) return false; $arFilter = $arParams['filter']; $arSelect = (isset($arParams['select'])) ? $arParams['select'] : false; $arSort = (isset($arParams['sort'])) ? $arParams['sort'] : array('name' =&gt; 'asc'); $pageParams = (isset($arParams['page_params'])) ? $arParams['page_params'] : false; $groupParams = (isset($arParams['group'])) ? $arParams['group'] : false; $return = false; $cache_params = array(); foreach (array_keys($arParams) as $array_key) { if (is_array($arParams[$array_key])) { foreach ($arParams[$array_key] as $key =&gt; $value) { $cache_params[$array_key . '-' . $key] = $value; } } elseif (is_bool($arParams[$array_key])) { $cache_params[$array_key] = $arParams[$array_key] ? 1 : 0; } } $cache_id = md5(serialize($cache_params)); $cache_dir = __CLASS__ . '/' . __FUNCTION__; $cache = \Bitrix\Main\Data\Cache::createInstance(); if ($life_time clean($cache_id, $cache_dir); } if ($cache-&gt;initCache($life_time, $cache_id, $cache_dir)) { $return = $cache-&gt;getVars(); } elseif ($cache-&gt;startDataCache() &amp;&amp; \Bitrix\Main\Loader::includeModule('iblock')) { if( is_array($arSelect) &amp;&amp; in_array('IBLOCK_ID',$arSelect) &amp;&amp; in_array('ID',$arSelect) ){ $filterProperties = array(); $filterFields = array(); foreach ($arSelect as $select) { if(strpos($select,'PROPERTY_')!==false){ $filterProperties[] = str_replace('PROPERTY_','',$select); } else { $filterFields[] = $select; } } $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $filterFields); while ($arElement = $rsItems-&gt;GetNextElement()) { $arFields = $arElement-&gt;GetFields(); if(!empty($filterProperties)){ foreach ($filterProperties as $arFilterCode){ if(!isset($arFields['PROPERTIES'])) $arFields['PROPERTIES'] = array(); $arFields['PROPERTIES'] = array_merge($arFields['PROPERTIES'],$arElement-&gt;GetProperties(false,array( 'CODE'=&gt;$arFilterCode ))); // $arFields['PROPERTIES'][$arFilterCode] = ; } // $arFields['PROPERTIES'] = $arElement-&gt;GetProperties(false,array('CODE'=&gt;$filterProperties)); } $return[] = $arFields; } } elseif (empty($arSelect)){ $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $arSelect); while ($arElement = $rsItems-&gt;GetNextElement()) { $arFields = $arElement-&gt;GetFields(); $arFields['PROPERTIES'] = $arElement-&gt;GetProperties(); $return[] = $arFields; } } else { $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $arSelect); while ($arElement = $rsItems-&gt;GetNext()) { $return[] = $arElement; } } if (!empty($return)) { foreach ($return as $key =&gt; $arItem) { if (!empty($arItem['PROPERTIES'])) { foreach ($arItem['PROPERTIES'] as $pCode =&gt; $arProperty) { $return[$key]['PROPERTIES'][$pCode] = \CIBlockFormatProperties::GetDisplayValue( array('ID' =&gt; $arItem['ID'], 'NAME' =&gt; $arItem['NAME']), $arProperty, ''); } } } } if(isset($pageParams) &amp;&amp; !empty($pageParams) &amp;&amp; $pageParams['nPageSize']==1 &amp;&amp; !empty($return[0])){ $return = $return[0]; } $return = array( 'ITEMS'=&gt;$return, 'MAX_CNT'=&gt;$rsItems-&gt;NavPageCount ); $cache-&gt;endDataCache($return); } $this-&gt;settings['ELEMENTS_CNT'] = $return['MAX_CNT']; return $return['ITEMS']; }

Получение информации об одном товаре

protected function GetIblockElementItems( $arParams = array('filter' =&gt; array(), 'select' =&gt; false, 'sort' =&gt; array('name' =&gt; 'asc'), 'page_params' =&gt; false, 'group' =&gt; false), $life_time = 3600) { if (!isset($arParams['filter']) || empty($arParams['filter'])) return false; $arFilter = $arParams['filter']; $arSelect = (isset($arParams['select'])) ? $arParams['select'] : false; $arSort = (isset($arParams['sort'])) ? $arParams['sort'] : array('name' =&gt; 'asc'); $pageParams = (isset($arParams['page_params'])) ? $arParams['page_params'] : false; $groupParams = (isset($arParams['group'])) ? $arParams['group'] : false; $return = false; $cache_params = array(); foreach (array_keys($arParams) as $array_key) { if (is_array($arParams[$array_key])) { foreach ($arParams[$array_key] as $key =&gt; $value) { $cache_params[$array_key . '-' . $key] = $value; } } elseif (is_bool($arParams[$array_key])) { $cache_params[$array_key] = $arParams[$array_key] ? 1 : 0; } } $cache_id = md5(serialize($cache_params)); $cache_dir = __CLASS__ . '/' . __FUNCTION__; $cache = \Bitrix\Main\Data\Cache::createInstance(); if ($life_time clean($cache_id, $cache_dir); } if ($cache-&gt;initCache($life_time, $cache_id, $cache_dir)) { $return = $cache-&gt;getVars(); } elseif ($cache-&gt;startDataCache() &amp;&amp; \Bitrix\Main\Loader::includeModule('iblock')) { if( is_array($arSelect) &amp;&amp; in_array('IBLOCK_ID',$arSelect) &amp;&amp; in_array('ID',$arSelect) ){ $filterProperties = array(); $filterFields = array(); foreach ($arSelect as $select) { if(strpos($select,'PROPERTY_')!==false){ $filterProperties[] = str_replace('PROPERTY_','',$select); } else { $filterFields[] = $select; } } $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $filterFields); while ($arElement = $rsItems-&gt;GetNextElement()) { $arFields = $arElement-&gt;GetFields(); if(!empty($filterProperties)){ foreach ($filterProperties as $arFilterCode){ if(!isset($arFields['PROPERTIES'])) $arFields['PROPERTIES'] = array(); $arFields['PROPERTIES'] = array_merge($arFields['PROPERTIES'],$arElement-&gt;GetProperties(false,array( 'CODE'=&gt;$arFilterCode ))); } } $return[] = $arFields; } } elseif (empty($arSelect)){ $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $arSelect); while ($arElement = $rsItems-&gt;GetNextElement()) { $arFields = $arElement-&gt;GetFields(); $arFields['PROPERTIES'] = $arElement-&gt;GetProperties(); $return[] = $arFields; } } else { $rsItems = \CIBlockElement::GetList($arSort, $arFilter, $groupParams, $pageParams, $arSelect); while ($arElement = $rsItems-&gt;GetNext()) { $return[] = $arElement; } } if (!empty($return)) { foreach ($return as $key =&gt; $arItem) { if (!empty($arItem['PROPERTIES'])) { foreach ($arItem['PROPERTIES'] as $pCode =&gt; $arProperty) { $return[$key]['PROPERTIES'][$pCode] = \CIBlockFormatProperties::GetDisplayValue( array('ID' =&gt; $arItem['ID'], 'NAME' =&gt; $arItem['NAME']), $arProperty, ''); } } } } if(isset($pageParams) &amp;&amp; !empty($pageParams) &amp;&amp; $pageParams['nPageSize']==1 &amp;&amp; !empty($return[0])){ $return = $return[0]; } $return = array( 'ITEMS'=&gt;$return, 'MAX_CNT'=&gt;$rsItems-&gt;NavPageCount ); $cache-&gt;endDataCache($return); } $this-&gt;settings['ELEMENTS_CNT'] = $return['MAX_CNT']; return $return['ITEMS']; }

Создание объекта IMagick

protected function ReadImage(){ try{ $this-&gt;_Imagick = new \Imagick(); $this-&gt;_Imagick-&gt;readImage($this-&gt;_absPath); } catch (Exception $e) { \CAdminMessage::ShowMessage($e-&gt;getMessage()); die(); } }

Создание результирующего изображения

public function CreateResultImage($width,$height){ // для начала заменим размеры изображения $blur = max( $this-&gt;_Imagick-&gt;getImageWidth() / $width, $this-&gt;_Imagick-&gt;getImageHeight()/$height); if($blur!==1){ $this-&gt;_Imagick-&gt;resizeImage($width,$height,null,$blur); } }

Создание миниатюр изображений в других цветах:

public function AddSamplesToMasterPhoto($arImages,$sampleWidth){ $arThumbs = array(); $labels = array(); $this-&gt;imgWidthStart = $sampleWidth* .1; foreach ($arImages as $arImage) { $thumb = new \Imagick(Application::getDocumentRoot().$arImage['SRC']); $thumb-&gt;adaptiveResizeImage($sampleWidth*.9, 0); $arThumbs[] = $thumb; $labels[] = $this-&gt;DrawImageColor($arImage,$sampleWidth*.9); } $maxHeight = 0; $maxLabelHeight = 0; foreach ($arThumbs as $num =&gt; $imagick) { $imgHeight = $imagick-&gt;getImageHeight(); $maxHeight = max($maxHeight,$imgHeight); $maxLabelHeight = max($maxLabelHeight, $labels[$num]-&gt;getImageHeight()); } // местоположение семплов должно быть на треть их высоты от края $offsetY = $this-&gt;_Imagick-&gt;getImageHeight() - $maxHeight*2; $labelOffsetY = $offsetY + $maxHeight*1.1; $offsetX = $sampleWidth*.1; foreach ($arThumbs as $num=&gt;$imagick) { $this-&gt;_Imagick-&gt;compositeImage($imagick,\Imagick::COMPOSITE_OVER, $offsetX, $offsetY); $this-&gt;_Imagick-&gt;compositeImage($labels[$num],\Imagick::COMPOSITE_OVER, $offsetX, $labelOffsetY); $offsetX += $sampleWidth*1.05; } $this-&gt;imgLastPos = $offsetY; }

Функция наложения текста на изображении

protected function DrawText($text,$size,$color,$bg=false,$maxWidth = false){ $draw = new \ImagickDraw(); $draw-&gt;setFillColor($color); $draw-&gt;setFontSize($size); $metrics = $this-&gt;_Imagick-&gt;queryFontMetrics($draw, $text); $image = new \Imagick(); if($bg){ $image-&gt;newImage($metrics['textWidth'], $metrics['textHeight'], $bg); } else { $image-&gt;newImage($metrics['textWidth'], $metrics['textHeight'], new \ImagickPixel('transparent')); } $draw-&gt;annotation(0, $metrics['ascender'], $text); $image-&gt;drawImage($draw); if($maxWidth &amp;&amp; $metrics['textWidth'] &gt; $maxWidth){ $image-&gt;adaptiveResizeImage($maxWidth,0); } return $image; }

В данной функции кроме непосрдественного вывода текста на изображении, реализован механизм отрисовки фоновой подложки под изображением. Если цвет фона задан - будет выведен он.

Сохранение полученных результатов

public function SaveResultImage($folder,$fileName){ if(!file_exists(Application::getDocumentRoot().$folder)){ mkdir(Application::getDocumentRoot().$folder); } $this-&gt;_Imagick-&gt;setImageFormat("jpg"); $this-&gt;_Imagick-&gt;writeImage(Application::getDocumentRoot().$folder.'/'.$fileName); }

Таким образом, в указанной менеджером папке на сайте будут размещены изображения с товарами и актуальной инфорвацией о товарах и их торговых предложениях.

Прикрепить файл

до 50мб