Изменение размера картинок на лету с кешированием

Статус
В этой теме нельзя размещать новые ответы.
  • Заблокирован
  • #11
прекрасно понял. я же говорю в дополнение.
кстати мод_реврайт замечательно решение. Потому как, иначе придется постоянно дергать пхп скрипт и передавать через него килобайты картинок, что тоже не очень хорошо скажется на ресурсах)
Мод_реврайт и обычная передача значений отличаются только внешним видом. Разве не так?
Разве мод_реврайт не будет каждый раз дёргать скрипт?:)
 
Мод_реврайт и обычная передача значений отличаются только внешним видом. Разве не так?
Разве мод_реврайт не будет каждый раз дёргать скрипт?:)
мод_реврайт работает еще до пхп. Сервер смотрит есть ли файл jpg(нужного размера), если есть - передает его юзеру. А вот в пхп передает запрос только в случае отсутствия jpg.
 
а не логичней ли было создавать уменьшенные экземпляры изображений в момент загрузки?...
если у вас новостной портал с посещалкой в 2к то за сутки явно будет обращение к изображениям любого размера
 
нельзя. ибо хостер требует деньги за растрату ресурсов)
 
Вот написал скрипт, который ресайзит, правда пока как проверить кешфайл непридумал, кроме как с помощью mod_rewrite

PHP:
<?php
//error_reporting(E_ALL & ~E_NOTICE);

$root_dir = getcwd();
$orig_dir = $root_dir."/uploads/";
$cache_dir = $root_dir."/uploads/cache/";

$max_size = $_GET['w'];

$filename = $_GET['file'];
$fileinfo = pathinfo($filename);

$sourcefile = $orig_dir.$filename;
$cachefile = $cache_dir."/".$fileinfo['dirname']."/".$fileinfo['basename']."_".$max_size.".".$fileinfo['extension'];

$params = getimagesize($sourcefile); 

switch ( $params[2] ) {
  case 1: $source = imagecreatefromgif($sourcefile); break;
  case 2: $source = imagecreatefromjpeg($sourcefile); break;
  case 3: $source = imagecreatefrompng($sourcefile); break;
} 

if ( $params[0]>$max_size || $params[1]>$max_size ) {

  if ( $params[0]>$params[1] ) $size = $params[0]; # ширина
  else $size = $params[1]; # высота

  $resource_width = floor($params[0] * $max_size / $size);
  $resource_height = floor($params[1] * $max_size / $size);

  # создание "подкладки"
  $resource = imagecreatetruecolor($resource_width, $resource_height);

  # изменение размера и копирование полученного на "подкладку"
  imagecopyresampled($resource, $source, 0, 0, 0, 0, $resource_width, $resource_height, $params[0], $params[1]);
}
# если изменять размер не надо просто присваиваем переменной $resource идентификатор оригинальной картинки
else $resource = $source;

switch ($fileinfo['extension']) {
	case "jpg":
		imagejpeg ($resource, $cachefile, 80);
		header("Content-type: image/jpeg");
		imagejpeg ($resource, "", 80);
	break;
	
	case "jpeg":
		imagejpeg ($resource, $cachefile, 80);
		header("Content-type: image/jpeg");
		imagejpeg ($resource, "", 80);
	break;
	
	case "png":
		imagepng ($resource, $cachefile);
		header("Content-type: image/png");
		imagepng ($resource);
	break;
	
	case "gif":
		imagegif ($resource, $cachefile);
		header("Content-type: image/gif");
		imagegif ($resource, "");
	break;
} 
?>

Кто подскажет как добавить проверку на существование кеша и его актуальность (например сутки)
 
можно сравнивать по дате изменения файолов filemtime().
если файл оригинала новее чем файл кеша - ресайзить заново
 
можно сравнивать по дате изменения файолов filemtime().
если файл оригинала новее чем файл кеша - ресайзить заново

До этого я не додумался!

Кто может написать как это реализовать?
php код всмысле

ОФФтоп: Как открыть файл и отправить в браузер?
 
ну здесь вроде просто.
PHP:
if( !file_exists($cachefile) || filemtime($sourcefile) > filemtime($cachefile)
{
//ресайзить
}
 
Так..вот написал с Вашей помощью скрипт полностью решающий задачу.

Где что можно оптимизировать?

PHP:
<?php
//error_reporting(E_ALL & ~E_NOTICE);
error_reporting(0);

$root_dir = getcwd();
$orig_dir = $root_dir."/uploads/";
$cache_dir = $root_dir."/uploads/cache/";

$max_size = intval($_GET['w']);

$filename = $_GET['file'];
$fileinfo = pathinfo($filename);

$sourcefile = $orig_dir.$filename;
if (!file_exists($sourcefile)) error();

$cachedir = $cache_dir."/".$fileinfo['dirname'];
if (!is_dir($cachedir)) mkdir($cachedir, 777, true);

$cachefile = $cachedir."/".$fileinfo['basename']."_".$max_size.".".$fileinfo['extension'];

if ((file_exists($cachefile))&&(filemtime($sourcefile)<filemtime($cachefile))) {
	$params = @getimagesize($sourcefile);
	switch ( $params[2] ) {
	  case 1: $source = header("Content-type: image/gif"); break;
	  case 2: $source = header("Content-type: image/jpeg"); break;
	  case 3: $source = header("Content-type: image/png"); break;
	} 
	echo file_get_contents($cachefile);
}
else {
	$params = @getimagesize($sourcefile); 
	if (($params[2]<1)||($params[2]>3)) error();

	switch ( $params[2] ) {
	  case 1: $source = imagecreatefromgif($sourcefile); break;
	  case 2: $source = imagecreatefromjpeg($sourcefile); break;
	  case 3: $source = imagecreatefrompng($sourcefile); break;
	} 

	if ($params[0]>$max_size) {

	  $resource_width = floor($max_size);
	  $resource_height = floor($params[1] * $max_size / $params[0]);

	  # создание "подкладки"
	  $resource = imagecreatetruecolor($resource_width, $resource_height);

	  # изменение размера и копирование полученного на "подкладку"
	  imagecopyresampled($resource, $source, 0, 0, 0, 0, $resource_width, $resource_height, $params[0], $params[1]);
	}
	# если изменять размер не надо просто присваиваем переменной $resource идентификатор оригинальной картинки
	else $resource = $source;

	switch ($fileinfo['extension']) {
		case "jpg":
			imagejpeg ($resource, $cachefile, 80);
			header("Content-type: image/jpeg");
			imagejpeg ($resource, "", 80);
		break;
		
		case "jpeg":
			imagejpeg ($resource, $cachefile, 80);
			header("Content-type: image/jpeg");
			imagejpeg ($resource, "", 80);
		break;
		
		case "png":
			imagepng ($resource, $cachefile);
			header("Content-type: image/png");
			imagepng ($resource);
		break;
		
		case "gif":
			imagegif ($resource, $cachefile);
			header("Content-type: image/gif");
			imagegif ($resource, "");
		break;
	}
}

function error() {
	header("HTTP/1.1 404 Not Found");
	header("Status: 404 Not Found");
	die();
}
?>


Появился еще вопрос

как браузеры и поисковики относятся к картинкам с адресом
PHP:
http://somesite/resize/40/http://somesite/uploads/files/290620101506.jpg
?
По этому адрессу путем правила mod_rewrite выполняется php-скрипт выше.
Что будет в таком случае с кешированием на стороне клиента?
Да если картинку по этому адресcу генерит php-скрипт как сделать чтобы он посылал браузеру что картинку можно закешировать, что она не изменилась например? Т.е. если мой скрипт открыл картинку из своего кеш-файла, а не сгенерил ее заново то он дает понять браузеру посетителя что ее можно кешировать на клиентской стороне..

Или же вообще лучше сделать так скрипт либо генерит файл, либо нет, но на выходе посылает header("Location: путь к реальному файлу") ?

Важно мнение спецов.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху