Создание сайтов на 1С-Битрикс

Уменьшение картинок в свойстве MORE_PHOTO

Если папка upload/iblock занимает много места и вы хотите уменьшить объем файлов, то это можно сделать уменьшив файлы в свойствах. Скрипт также конвертирует файлы PNG в JPG и удаляет ссылки на файлы, которые были удалены с сервера.

Перед процедурой нужно создать в инфоблоке свойство с кодом TEST (потом можно удалить). Далее сохраняем код в файл php в любом месте на сервере (например, в корне под именем test.php).

Рекомендую перед применением сделать резервную копию и попробовать сначала на одном/нескольких элементах. Для теста нужно раскомментировать строчку в коде и вставить ID нужного элемента.

Скрипт доступен только администраторам (строчка с $USER->IsAdmin()).

<?
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');
$APPLICATION->SetTitle("test");
error_reporting(E_ERROR);

global $USER;
if (!$USER->IsAdmin()) die("Доступ запрещен");


$hasError = false;
$hasEls = 0;

// Для элементов
if(CModule::IncludeModule('iblock')) {
  
  $iblockID = 26;
  $propCode = 'MORE_PHOTO';
  $maxSize = 1200;
  $jpegQuality = 90;

    $arSelect = Array("ID", "IBLOCK_ID", "NAME");
    $arFilter = Array("IBLOCK_ID"=>$iblockID, "PROPERTY_TEST"=>false);
    // Раскомментировать для тестирования на одном элементе (подставить нужный ID элемента)
    // $arFilter = Array("IBLOCK_ID"=>$iblockID, "ID"=>100);
    
    $res = CIBlockElement::GetList(Array("ID"=>"ASC"), $arFilter, false, ['nTopCount' => 30], $arSelect);


    while($arItem = $res->Fetch()){ 

      $tmpFiles = array();
      $MORE_PHOTO = array();
      $changed = false;
      $hasEls++;
      $addText = '';

      $res2 = CIBlockElement::GetProperty($iblockID, $arItem['ID'], array("sort" => "asc", "id" => "desc"), array("CODE" => $propCode));
      while ($ob = $res2->GetNext())
      {
        $MORE_PHOTO[] = CFile::GetById($ob['VALUE'])->Fetch();
      }

      $hasNeedFiles = false;

      foreach ($MORE_PHOTO as $img) {
        if($img['CONTENT_TYPE'] == 'image/png' || $img['WIDTH'] > $maxSize || $img['HEIGHT'] > $maxSize) {
          $hasNeedFiles = true;
          break;
        }
      }

      if($hasNeedFiles) {
        foreach ($MORE_PHOTO as $key => &$img) {

          $imgSrc = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"].$img['SRC']);
          $description = $img['DESCRIPTION'];
          // Раскомментировать строчку чтобы в описании было название файла
          // if(!$description) $description = $img['ORIGINAL_NAME'];

          if($imgSrc) {

            if($img['CONTENT_TYPE'] == 'image/png') {
                $image = imagecreatefrompng($imgSrc['tmp_name']);
                $src_w = imagesx($image);
                $src_h = imagesy($image);

                $bg = imagecreatetruecolor($src_w, $src_h);
                imagefill($bg, 0, 0, imagecolorallocate($bg, 255, 255, 255));
                imagealphablending($bg, TRUE);

                if($src_w > $maxSize || $src_h > $maxSize) {
                  // resize
                  $ratio = $src_w / $src_h;
                  if($ratio >= 1) {
                    $newWidth = $maxSize;
                    $newHeight = round($newWidth / $ratio);
                  } else {
                    $newHeight = $maxSize;
                    $newWidth = round($newHeight * $ratio);
                  }
                  $bg = imagecreatetruecolor($newWidth, $newHeight);
                  imagecopyresampled($bg, $image, 0, 0, 0, 0, $newWidth, $newHeight, $src_w, $src_h);
                } else {
                  imagecopy($bg, $image, 0, 0, 0, 0, $src_w, $src_h);
                }

                imagedestroy($image);
                $tmpFile = $_SERVER["DOCUMENT_ROOT"].'/upload/tmp/'.str_replace('.png', '.jpg', $imgSrc['name']);
                if($bg) {
                  imagejpeg($bg, $tmpFile, $jpegQuality);
                }
                imagedestroy($bg);

                $tmpFiles[] = $tmpFile;

                $img = CFile::MakeFileArray($tmpFile);
                $img['description'] = $description;
                $changed = true;

            } elseif($img['WIDTH'] > $maxSize || $img['HEIGHT'] > $maxSize) {
                // resize
                $tmpFile = $_SERVER["DOCUMENT_ROOT"].'/upload/tmp/'.$img['FILE_NAME'];
                $result = CFile::ResizeImageFile( // уменьшение картинки для превью
                    $imgSrc['tmp_name'],
                    $tmpFile,
                    array('width'=>$maxSize,'height'=>$maxSize),
                    ($img['WIDTH'] >= $img['HEIGHT'])? BX_RESIZE_IMAGE_PROPORTIONAL : BX_RESIZE_IMAGE_PROPORTIONAL_ALT,
                    array(),
                    $jpegQuality,
                    false
                );
                if ($result) {
                  $img = CFile::MakeFileArray($tmpFile);
                  $img['description'] = $description;
                  $tmpFiles[] = $tmpFile;
                  $changed = true;
                } else {
                  $addText = 'Ошибка уменьшения файла: '.$img['SRC'].'<br>';
                  $hasError = true;
                }
            } else {
              // normal
              $img = CFile::MakeFileArray($imgSrc['tmp_name']);
            }
            $img['description'] = $description;

          } else {
            $addText = 'Не найден файл: '.$img['FILE_NAME'].' — удаляем<br>';
            $img = array("VALUE" => "", "DESCRIPTION" => "");
            $changed = true;
          }
          
        }
      }

      if(!$hasError) {
        CIBlockElement::SetPropertyValuesEx($arItem['ID'], $iblockID, array('TEST' => 'Y'));
      }

      if($changed) {
        CIBlockElement::SetPropertyValuesEx($arItem['ID'], $iblockID, array($propCode => $MORE_PHOTO));
      }

      foreach ($tmpFiles as $file) {
        unlink($file);
      }

      echo 'ID: '.$arItem['ID'].' - '.$arItem['NAME'].'<br>';
      if($addText) {
        echo $addText;
      }
      echo '<br>';

    }   
}


if(!$hasError && $hasEls) {
    echo '<br><br><div id="success">Успешно</div>';
}

?>
<script>
document.addEventListener("DOMContentLoaded", function() {
    'use strict';

    let success = document.getElementById('success');

    if(success) {
        setTimeout(() => {
            location.reload();
        }, 500);
    }
});
</script>



А код ниже можно добавить в init.php для уменьшения картинок в автоматическом режиме (при добавлении или изменении элемента):

<?
// Уменьшение картинок в свойстве MORE_PHOTO
AddEventHandler("iblock", "OnAfterIBlockElementAdd", Array("MorePhotoResizeClass", "OnAfterIBlockElement"));
AddEventHandler("iblock", "OnAfterIBlockElementUpdate", Array("MorePhotoResizeClass", "OnAfterIBlockElement"));

class MorePhotoResizeClass
{
   static function Clear()
   {
      $_WFILE = glob($_SERVER['DOCUMENT_ROOT']."/upload/tmp/*");
      foreach($_WFILE as $_file) unlink($_file);
      return true;
   }
 
   static function OnAfterIBlockElement(&$arFields)
   {
      global $APPLICATION, $USER;
      
      $arProp = array();

      $PROPERTY_CODE = "MORE_PHOTO"; // Код свойства с которым работаем

      $imageWidth = 1400; // Максимальная ширина уменьшенной картинки
      $imageHeight = 1400; // Максимальная высота уменьшенной картинки
      
      // Находим свойство
      $dbRes = CIBlockElement::GetProperty($arFields["IBLOCK_ID"], $arFields["ID"], "sort", "asc", array("CODE" => $PROPERTY_CODE));
      
      while ($arMorePhoto = $dbRes->GetNext(true, false))
      {
         if ($arMorePhoto["PROPERTY_TYPE"] == "F" && $arMorePhoto["MULTIPLE"] == "Y")
         {
            // Находим подробные сведения о файле
            $arFile = CFile::GetFileArray($arMorePhoto["VALUE"]);

            // Проверяем, что файл является картинкой
            if (!CFile::IsImage($arFile["FILE_NAME"])) continue;

            // Если размер больше допустимого
            if ($arFile["WIDTH"] > $imageWidth || $arFile["HEIGHT"] > $imageHeight)
            {
               // Временная картинка
               $tmpFilePath = $_SERVER['DOCUMENT_ROOT']."/upload/tmp/".$arFile["FILE_NAME"];

               // Уменьшаем картинку
               $resizeRez = CFile::ResizeImageFile(
                  $sourceFile = $_SERVER['DOCUMENT_ROOT'].$arFile["SRC"],
                  $destinationFile = $tmpFilePath,
                  $arSize = array('width' => $imageWidth, 'height' => $imageHeight),
                  $resizeType = BX_RESIZE_IMAGE_PROPORTIONAL,
                  $waterMark = array(
                     "type" => "image",
                     "position" => "tr",
                     "size" => "real",
                     "file" => $_SERVER['DOCUMENT_ROOT'].'/watermark.png',
                  ),
                  $jpgQuality = 95
               );

               // Записываем изменение в массив
               if ($resizeRez)
               {
                  $arProp += array(
                     $arMorePhoto["PROPERTY_VALUE_ID"] => array(
                        "VALUE" => CFile::MakeFileArray($tmpFilePath),
                        "DESCRIPTION"=> $arMorePhoto["DESCRIPTION"]
                     )
                  );
               }
            }
         }
      }
      
      if (!empty($arProp))
      {
         // Записываем изменение в свойство
         CIBlockElement::SetPropertyValueCode($arFields["ID"], $PROPERTY_CODE, $arProp);
         
         // Стираем временные файлы
         MorePhotoResizeClass::Clear();
      }
   }
}

Разумеется символы <? нужны только в начале файла init.php ))
Логотип SiteBERG
Изменено: 23.06.2026 18:15

Статьи

Что нужно сделать?