Часто на сайтах нужно ресайзить рисунки и в большинстве случаев это выглядит так:
Такой метод имеет ряд очевидных недостатков:
И конечно же есть метод ресайза рисунков, который лишен этих недостатков. Суть его в следующем:
c помощью модуля mod_rewrite мы можем контролировать выдачу файлов с каталога отресайзенных рисунков таким образом, что если файла не существует мы передаем управление PHP скрипту, который и создаст отресайзенное изображение, а затем отдаст его браузеру.
Таким образом, PHP скрипт будет запрошен только раз, а дальше веб-сервер будет отдавать рисунок как обычно.
Идея, понятно, не новая. В интернете нашел несколько упоминаний о таком подходе, но реализация мне не понравилась. Поэтому я решил создать свойкостыль набор скриптов для этого дела.
Итак, первым делом в папку, где будут хранится отресайзенные рисунки положим .htaccess файл примерно такого содержания:
В зависимости от структуры ваших директорий замените RewriteBase и путь к resize_handler.php.
Сам resize_handler.php у меня получился таким:
PHPThumbResizer — это класс, который наследует мой LazyResizer и реализует метод resizeAndSave.
LazyResizer я создавал без реализации самого ресайза изображений чтобы пользователь мог подключить его любимую библиотеку для ресайза.
В месте, куда нужно вставить URL отресайзенного изображения, код может выглядеть так:
В итоге получаем
Во-первых, рисунки будут иметь такой же путь как и оригинал, только с префиксом imgcache (или как вы назовете папку с кэшем) и с модифицированным названием файла.
Во-вторых, в названии отресазенного риунка можно увидеть 6 символов контрольной суммы, за которой через дефис следует размер. Контрольная сумма нужна для того, чтобы
Реализацию, которую я назвал Lazy Resizer, можно найти на github.
В качестве библиотеки ресайза, я взял PHPThumb, но как говорилось выше, можно подключить и другую библиотеку.
- во время генерации страницы запускается скрипт с адресом рисунка и параметрами ресайза;
- скрипт проверяет нет ли уже отрезайзеного файла на сервере;
- если его нет, то запускается процес ресайза и сохранения файла.
Такой метод имеет ряд очевидных недостатков:
- замедляется генерация страницы (особенно если нужно ресайзить много рисунков);
- отресайзенные рисунки не всегда будут запрошены клиентом.
И конечно же есть метод ресайза рисунков, который лишен этих недостатков. Суть его в следующем:
c помощью модуля mod_rewrite мы можем контролировать выдачу файлов с каталога отресайзенных рисунков таким образом, что если файла не существует мы передаем управление PHP скрипту, который и создаст отресайзенное изображение, а затем отдаст его браузеру.
Таким образом, PHP скрипт будет запрошен только раз, а дальше веб-сервер будет отдавать рисунок как обычно.
Идея, понятно, не новая. В интернете нашел несколько упоминаний о таком подходе, но реализация мне не понравилась. Поэтому я решил создать свой
Итак, первым делом в папку, где будут хранится отресайзенные рисунки положим .htaccess файл примерно такого содержания:
RewriteEngine On
RewriteBase /lazyresizer/imgcache
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /lazyresizer/lazyresizer/resize_handler.php?path=$1 [L,QSA]
В зависимости от структуры ваших директорий замените RewriteBase и путь к resize_handler.php.
Сам resize_handler.php у меня получился таким:
include_once 'PHPThumbResizer.php';
try {
if ($_GET['path']) {
PHPThumbResizer::replaceResized($_GET['path']);
}
} catch (Exception $e) {
header('HTTP/1.1 500 Internal Server Error');
echo '<!DOCTYPE HTML>
<meta charset="utf-8">
<title>500 Internal Server Error</title>
<h1>Error</h1>
<p>'.$e->getMessage().'</p>';
}
PHPThumbResizer — это класс, который наследует мой LazyResizer и реализует метод resizeAndSave.
LazyResizer я создавал без реализации самого ресайза изображений чтобы пользователь мог подключить его любимую библиотеку для ресайза.
В месте, куда нужно вставить URL отресайзенного изображения, код может выглядеть так:
<?
$original = 'images/abstract-images/01.jpg';
include_once 'lazyresizer/PHPThumbResizer.php';
?>
<table>
<tr>
<td><img src="<?= $original ?>" /></td>
<td><img src="<?= PHPThumbResizer::resizedPath($original, 200, 200) ?>" /></td>
<td><img src="<?= PHPThumbResizer::resizedPath($original, 50, 100, array('mode' => 'adaptive')) ?>" /></td>
</tr>
<tr>
<th>Original</th>
<th>200x200</th>
<th>50x100 (adaptive mode)</th>
</tr>
</table>
В итоге получаем
<table>
<tr>
<td><img src="images/abstract-images/01.jpg" /></td>
<td><img src="imgcache/images/abstract-images/01(9bcfbe-200x200).jpg" /></td>
<td><img src="imgcache/images/abstract-images/01(a7fd45-50x100).jpg?mode=adaptive" ></td>
</tr>
<tr>
<th>Original</th>
<th>200x200</th>
<th>50x100 (adaptive mode)</th>
</tr>
</table>
Особенности реализации
Во-первых, рисунки будут иметь такой же путь как и оригинал, только с префиксом imgcache (или как вы назовете папку с кэшем) и с модифицированным названием файла.
Во-вторых, в названии отресазенного риунка можно увидеть 6 символов контрольной суммы, за которой через дефис следует размер. Контрольная сумма нужна для того, чтобы
- при изменении оригинала не выдавался старый отресазенный рисунок;
- веб-пользователи не смогли забить сервер ресайзингом рисунков простым изменением названия кеш-файла;
- можно было создавать несколько типов отресазенных рисунков в зависимости от GET параметров.
Реализацию, которую я назвал Lazy Resizer, можно найти на github.
В качестве библиотеки ресайза, я взял PHPThumb, но как говорилось выше, можно подключить и другую библиотеку.