Перед процедурой нужно создать в инфоблоке свойство с кодом 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 ))
