Доброго времени суток.
Работаем на Битриксе с 2013 года. На данный момент номенклатура насчитывает около 7000 товаров.
За это время поменялось куча контент манагеров, которые занимались заполнением карточек товаров.
Делая в очередной раз бекап обнаружил, что его размер уже почти 12 Gb (учитывая что пару лет назад было 5000 товаров и размер архива был около 6 Gb)
Первая проблема - очень много "мёртвых" изображений. Т.е. тех, которые раньше были привязаны к какому либо инфоблоку (товару), впоследствии товар был удален, а файлы на сервере так и висят.
С этой проблемой боролся найденым в интернете способом:
В файл /bitrix/php_interface/init.php в конец добавляем код:
Затем добавляем агента с необходимой Вам периодичностью (я поставил себе 30 дней) и ждём выполнения
Изначально запускал скрипт (и Вам советую) со следующими значениями переменных:
$deleteFiles = 'yes';
$saveBackup = 'yes';
В этом случае все удаляемые файлы из папки "/upload/iblock/" помещаются в папку "/upload/iblock_Backup/" и их можно (в случае чего) восстановить.
Однако "сжатие" оказалось не сильно эффективным в моём случае. Размер папки "/upload/iblock" уменьшился с 9,33 Gb до 8,69 Gb
Просмотрев некоторые изображения (выборочно), понял что очень много файлов закачивалось вообще без сжатия:
И да, я понимаю что за это нужно надавать по голове контентщикам... Но файлы УЖЕ загружены и нужно что-то делать прямо сейчас.
Наваял скрипт, который, надеюсь, поможет и Вам. Вставлять всё в тот же /bitrix/php_interface/init.php
В функции CompressImages() в строке compress_image($file,$file, 1200, 75);
1200 - ширина изображения,
75 - процент сжатия
Создал так же с периодичностью месяц агента "CompressImages();"
Результат выполнения агента - уменьшение размера папки с 8.69 до 4.7, т.е. практически в 2 раза...
До:
После:
Остался доволен как слон.
Скрипт проверяет размер изображения. Если его ширина меньше 1200, то размер изображения не меняется.
Если больше - уменьшается до ширины 1200.
Пропорции остаются неизменными.
Обрабатываются файлы jpg и png
Прозрачность png при сжатии не теряется.
Вдруг кому пригодится...
Всем бобра!
Работаем на Битриксе с 2013 года. На данный момент номенклатура насчитывает около 7000 товаров.
За это время поменялось куча контент манагеров, которые занимались заполнением карточек товаров.
Делая в очередной раз бекап обнаружил, что его размер уже почти 12 Gb (учитывая что пару лет назад было 5000 товаров и размер архива был около 6 Gb)
Первая проблема - очень много "мёртвых" изображений. Т.е. тех, которые раньше были привязаны к какому либо инфоблоку (товару), впоследствии товар был удален, а файлы на сервере так и висят.
С этой проблемой боролся найденым в интернете способом:
В файл /bitrix/php_interface/init.php в конец добавляем код:
Код |
---|
// Очистка папки /upload/iblock от ненужных изображений function CleanUpUpload() { global $DB; define("NO_KEEP_STATISTIC", true); define("NOT_CHECK_PERMISSIONS", true); $deleteFiles = 'yes'; //Удалять ли найденые файлы yes/no $saveBackup = 'no'; //Создаст бэкап файла yes/no //Папка для бэкапа $patchBackup = $_SERVER['DOCUMENT_ROOT'] . "/upload/iblock_Backup/"; //Целевая папка для поиска файлов $rootDirPath = $_SERVER['DOCUMENT_ROOT'] . "/upload/iblock"; $time_start = microtime(true); //Создание папки для бэкапа if (!file_exists($patchBackup)) { CheckDirPath($patchBackup); } // Получаем записи из таблицы b_file $arFilesCache = array(); $result = $DB->Query('SEL ECT FILE_NAME, SUBDIR FR OM b_file WHERE MODULE_ID = "iblock"'); while ($row = $result->Fetch()) { $arFilesCache[$row['FILE_NAME']] = $row['SUBDIR']; } $hRootDir = opendir($rootDirPath); $count = 0; $contDir = 0; $countFile = 0; $i = 1; $removeFile=0; while (false !== ($subDirName = readdir($hRootDir))) { if ($subDirName == '.' || $subDirName == '..') { continue; } //Счётчик пройденых файлов $filesCount = 0; $subDirPath = "$rootDirPath/$subDirName"; //Путь до подкатегорий с файлами $hSubDir = opendir($subDirPath); while (false !== ($fileName = readdir($hSubDir))) { if ($fileName == '.' || $fileName == '..') { continue; } $countFile++; if (array_key_exists($fileName, $arFilesCache)) { //Файл с диска есть в списке файлов базы - пропуск $filesCount++; continue; } $fullPath = "$subDirPath/$fileName"; // полный путь до файла $backTrue = false; //для создание бэкапа if ($deleteFiles === 'yes') { if (!file_exists($patchBackup . $subDirName)) { if (CheckDirPath($patchBackup . $subDirName . '/')) { //создал поддиректорию $backTrue = true; } } else { $backTrue = true; } if ($backTrue) { if ($saveBackup === 'yes') { CopyDirFiles($fullPath, $patchBackup . $subDirName . '/' . $fileName); //копия в бэкап } } //Удаление файла if (unlink($fullPath)) { $removeFile++; } } else { $filesCount++; } $i++; $count++; unset($fileName, $backTrue); } closedir($hSubDir); //Удалить поддиректорию, если удаление активно и счётчик файлов пустой - т.е каталог пуст if ($deleteFiles && !$filesCount) { rmdir($subDirPath); } $contDir++; } closedir($hRootDir); return "CleanUpUpload();"; } // Конец очистки |
Скрытый текст |
---|
$deleteFiles = 'yes';
$saveBackup = 'yes';
В этом случае все удаляемые файлы из папки "/upload/iblock/" помещаются в папку "/upload/iblock_Backup/" и их можно (в случае чего) восстановить.
Однако "сжатие" оказалось не сильно эффективным в моём случае. Размер папки "/upload/iblock" уменьшился с 9,33 Gb до 8,69 Gb
Просмотрев некоторые изображения (выборочно), понял что очень много файлов закачивалось вообще без сжатия:
Скрытый текст |
---|
И да, я понимаю что за это нужно надавать по голове контентщикам... Но файлы УЖЕ загружены и нужно что-то делать прямо сейчас.
Наваял скрипт, который, надеюсь, поможет и Вам. Вставлять всё в тот же /bitrix/php_interface/init.php
Код |
---|
//Сжатие изображений class SimpleImage { var $image; var $image_type; function load($filename) { $image_info = getimagesize($filename); $this->image_type = $image_info[2]; if( $this->image_type == IMAGETYPE_JPEG ) { $this->image = imagecreatefromjpeg($filename); } elseif( $this->image_type == IMAGETYPE_GIF ) { $this->image = imagecreatefromgif($filename); } elseif( $this->image_type == IMAGETYPE_PNG ) { $this->image = imagecreatefrompng($filename); } } function save($filename, $compression=75, $image_type=IMAGETYPE_JPEG, $permissions=null) { // do this or they'll all go to jpeg $image_type=$this->image_type; if( $image_type == IMAGETYPE_JPEG ) { imagejpeg($this->image,$filename,$compression); } elseif( $image_type == IMAGETYPE_GIF ) { imagegif($this->image,$filename); } elseif( $image_type == IMAGETYPE_PNG ) { // need this for transparent png to work imagealphablending($this->image, false); imagesavealpha($this->image,true); imagepng($this->image,$filename); } if( $permissions != null) { chmod($filename,$permissions);} } function output($image_type=IMAGETYPE_JPEG) { if( $image_type == IMAGETYPE_JPEG ) { imagejpeg($this->image); } elseif( $image_type == IMAGETYPE_GIF ) { imagegif($this->image); } elseif( $image_type == IMAGETYPE_PNG ) { imagepng($this->image); } } function getWidth() { return imagesx($this->image); } function getHeight() { return imagesy($this->image); } function resizeToHeight($height) { $ratio = $height / $this->getHeight(); $width = $this->getWidth() * $ratio; $this->resize($width,$height); } function resizeToWidth($width) { $ratio = $width / $this->getWidth(); $height = $this->getheight() * $ratio; $this->resize($width,$height); } function scale($scale) { $width = $this->getWidth() * $scale/100; $height = $this->getheight() * $scale/100; $this->resize($width,$height); } function resize($width,$height,$forcesize='n') { /* optional. if file is smaller, do not resize. */ if ($forcesize == 'n') { if ($width > $this->getWidth() && $height > $this->getHeight()){ $width = $this->getWidth(); $height = $this->getHeight(); } } $new_image = imagecreatetruecolor($width, $height); /* Check if this image is PNG or GIF, then set if Transparent*/ if(($this->image_type == IMAGETYPE_GIF) || ($this->image_type==IMAGETYPE_PNG)){ imagealphablending($new_image, false); imagesavealpha($new_image,true); $transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127); imagefilledrectangle($new_image, 0, 0, $width, $height, $transparent); } imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight()); $this->image = $new_image; } } function compress_image($source_url, $destination_url, $width=1600, $compression=75) { $image = new SimpleImage(); $image->load($source_url); $image->resizeToWidth((int)$width); $image->save($destination_url,$compression); } function getDirContents($dir, &$results = array()){ $files = scandir($dir); foreach($files as $key => $value){ $path = realpath($dir.DIRECTORY_SEPARATOR.$value); if(!is_dir($path)) { if (in_array(mime_content_type($path), array("image/jpeg", "image/pjpeg", "image/png"))) $results[] = $path; } else if($value != "." && $value != "..") { getDirContents($path, $results); //if (filetype($path) == 'file') { //$results[] = $path; //} } } return $results; } function CompressImages() { $rd = $_SERVER["DOCUMENT_ROOT"]; $files = getDirContents($rd.'/upload/iblock'); foreach ($files as $file) { compress_image($file,$file, 1200, 75); } return "CompressImages();"; } //Конец сжатия изображений |
В функции CompressImages() в строке compress_image($file,$file, 1200, 75);
1200 - ширина изображения,
75 - процент сжатия
Создал так же с периодичностью месяц агента "CompressImages();"
Скрытый текст |
---|
Результат выполнения агента - уменьшение размера папки с 8.69 до 4.7, т.е. практически в 2 раза...
До:
Скрытый текст |
---|
Скрытый текст |
---|
Остался доволен как слон.
Скрипт проверяет размер изображения. Если его ширина меньше 1200, то размер изображения не меняется.
Если больше - уменьшается до ширины 1200.
Пропорции остаются неизменными.
Обрабатываются файлы jpg и png
Прозрачность png при сжатии не теряется.
Вдруг кому пригодится...
Всем бобра!