Массовое изменение формата изображений в WordPress

17.09.2019

Задача: на сайте более 1000 изображений в png формате, движок Wordpress, надо все изображения перевести в jpg и изменить расширение с png на jpg.

Для начала результаты тестов: оказалось что аналогичные jpg файлы весят от 1,5 до 5 раз меньше нежели png файлы, причем без потери качества.

Обновление базы данных

Для того чтобы сделать SQL запрос, необходимо войти в веб интерфейс phpMyAdmin соответствующей базы данных, затем перейти во вкладку SQL.

Таблица wp_posts

Замена значений post_mime_type и расширения в guid (видимо ссылка на изображение) у всех постов с post_type равным attachment и post_mime_type равным image/png:

•••
sql
UPDATE `wp_posts` SET `post_mime_type`='image/jpg', `guid`=REPLACE(`guid`, '.png', '.jpg') WHERE `post_type`='attachment' and `post_mime_type`='image/png'

Замена во всех постах расширения в ссылках на изображения:

•••
sql
UPDATE 'wp_posts' SET 'post_content'=REPLACE('post_content', '.png', '.jpg') WHERE 'post_type'='post'

Таблица wp_postmeta

Замена расширения файлов в meta_value у тех строк таблицы, которые имеют meta_key равным _wp_attached_file:

•••
sql
UPDATE 'wp_postmeta' SET 'meta_value'=REPLACE('meta_value', '.png', '.jpg') WHERE 'meta_key'='_wp_attached_file'`

Замена расширения файлов в meta_value у тех строк таблицы, которые имеют meta_key равным _wp_attachment_metadata:

•••
sql
UPDATE 'wp_postmeta' SET 'meta_value'=REPLACE('meta_value', '.png', '.jpg') WHERE 'meta_key'='_wp_attachment_metadata'

Замена значения meta_value у тех строк таблицы, которые имеют meta_key равным _wp_attachment_metadata:

•••
sql
UPDATE 'wp_postmeta' SET 'meta_value'=REPLACE('meta_value', 'image/png', 'image/jpg') WHERE 'meta_key'='_wp_attachment_metadata'

Конвертирование файлов на сервере

Необходимо конвертировать все изображения на сервере и изменить расширения при помощи php скрипта extensionedit.php, который разместим в директории wp-content:

•••
php
set_time_limit(0); //! пути относительно скрипта, откуда берем картинки $g_aSrcPath = array( "uploads/2017", "uploads/2018" ); //! $g_sExtCurr = "png"; $g_sExtNew = "jpg"; //************************************************************************** //! сканируем директорию, на выходе получаем все пути до файлов (в том числе и вложенных) function ScanPath($dir) { $d = array(); $arr = opendir($dir); while($v = readdir($arr)) { if($v == '.' or $v == '..') continue; if(!is_dir($dir.DIRECTORY_SEPARATOR.$v)) $d[] = $v; if(is_dir($dir.DIRECTORY_SEPARATOR.$v)) { $aArr = ScanPath($dir.DIRECTORY_SEPARATOR.$v); for($i=0, $il=count($aArr); $i<$il; ++$i) { $d[] = $v.DIRECTORY_SEPARATOR.$aArr[$i]; } } } return $d; } //! загрузка изображения, возвращает resource function LoadImg($sPath) { return imagecreatefromstring(file_get_contents($sPath)); } function GetExtension($sFile) { return substr(strrchr($sFile, '.'), 1); } //************************************************************************** // if(!empty($g_sExtCurr) && !empty($g_sExtNew)) { $iCountEdit = 0; //проходимся по всем указанным путям, ищем изображения for($i=0, $il=count($g_aSrcPath); $i<$il; ++$i) { //получаем список файлов (с путями) $aFiles = ScanPath($g_aSrcPath[$i]); //проходимся по списку файлов for($k=0, $kl=count($aFiles); $k<$kl; ++$k) { if(mb_stripos($aFiles[$k], "favicon") !== false) continue; $sSrcParh = $g_aSrcPath[$i].DIRECTORY_SEPARATOR.$aFiles[$k]; //echo $sSrcParh . "|" . GetExtension($sSrcParh); if(GetExtension($sSrcParh) == $g_sExtCurr) { $sFileName = basename($sSrcParh, "." . $g_sExtCurr); $sNewParh = dirname($sSrcParh); $sNewParh = $sNewParh.DIRECTORY_SEPARATOR.$sFileName.".".$g_sExtNew; $hSrcImg = LoadImg($sSrcParh); rename($sSrcParh,$sNewParh); imagejpeg($hSrcImg, $sNewParh, 100); ++$iCountEdit; } } } echo "Edit extension " . $iCountEdit . " files"; } else { http_response_code(404); die; } ?>

Запуск скрипта: my-site.ru/wp-content/extensionedit.php

Ссылки на изображения на сторонних сайтах

Будет плохо если ссылки на png файлы будут битыми, поэтому надо сделать чтобы они стали доступны, но с редиректом.

Для этого в файл .htaccess нужно добавить (перед всеми правилами):

•••
plaintext
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(wp\-content/uploads/.*)\.png$ /$1.jpg [L,QSA]

Мой итоговый .htaccess для Wordpress:

•••
plaintext
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(wp\-content/uploads/.*)\.png$ /$1.jpg [L,QSA] RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress

Теперь все изображения доступны и по адресу с png расширение, однако с редиректом.

Итог

  • Размер до конвертирования: 1,64 гб
  • Размер после конвертирования: 926 мб
  • Экономия места: 753 мб
  • Коэффициент сжатия: 1,81