PHP: пропорциональное уменьшение изображения
Фух. Наконец-то появилось свободное время — завершил все заказы по верстке, написал с нуля небольшой веб сервис (о нём я расскажу позже. В конце августа или в начале сентября), а теперь напишу небольшой урок по php. Хотя в дальнейшем я буду публиковать новые уроки по программированию. Буду рассматривать свои «старые» скрипты, а также делиться опытом в «прямом эфире» — т.е. научился чему-либо, попробую научить и вас.
Сегодня я разберу скрипт своего старого музыкального портала, который я написал в далёком 2005 году, когда ещё не кто и не мечтал о верстке дивами и все верстали таблицами. =) Тогда наверно и не существовало html-верстальщиков — ибо один человек мог напсать с нуля статическую домашнюю страничку и гордиться этим.
Следовательно, мой сайт был сверстан таблицами и у меня появилась проблема. Поскольку любой пользователь могу добавить в галерею сайта фотографии, то фотографий в галереи было много и они были разного размера, но фотогалерея сайта была задумана так, чтобы фотографии размещались по 4 штуки на строку и было 5 строк на странице. Естественно в полный размер фото бы не уместились и появился бы горизонтальный скролл. Тогда я решил написать скрипт, который при загрузке фото на сервер, создавал бы уменьшенную копию фотографии с шириной 150 пикселей, не теряя при этом пропорций фотографии. Забыл сказать, данный скрипт расчитан на jpg изображения т.к. подавляющее большинство фотографий делаются в это формате.
Ниже представлен весь необходимый нам, для выполнения нашей задачи, код. Приступаю к комментированию.
|
А вот и код
|
|
<?php
#Определяем размер фотографии — ширину и высоту $size=GetImageSize («photo.jpg»); #Создаём новое изображение из «старого» $src=ImageCreateFromJPEG («photo.jpg»); #Берём числовое значение ширины фотографии, которое мы получили в первой строке и записываем это число в переменную $iw=$size[0]; #Проделываем ту же операцию, что и в предыдущей строке, но только уже с высотой. $ih=$size[1]; #Ширину фотографии делим на 150 т.к. на выходи мы хотим получить фото шириной в 150 пикселей. В результате получаем коэфициент соотношения ширины оригинала с будущей превьюшкой. $koe=$iw/150; #Делим высоту изображения на коэфициент, полученный в предыдущей строке, и округляем число до целого в большую сторону — в результате получаем высоту нового изображения. $new_h=ceil ($ih/$koe); #Создаём пустой изображени шириной в 150 пикселей и высотой, которую мы вычислили в предыдущей строке. $dst=ImageCreateTrueColor (150, $new_h); #Данная функция копирует прямоугольную часть изображения в другое изображение, плавно интерполируя пикселные значения таким образом, что, в частности, уменьшение размера изображения сохранит его чёткость и яркость. ImageCopyResampled ($dst, $src, 0, 0, 0, 0, 150, $new_h, ImageSX ($src), ImageSY ($src)); #Сохраняем полученное изображение в формате JPG ImageJPEG ($dst, «small_photo.jpg», 100); ?> |
Пример работы скрипта вы можете посмотреть здесь. Исходное изображение находится тут. Если хоите, то можете уменьшить любое другое изображение. Для этого передайте скрипту адрес изображения в виде http://www.zhitenev.ru/demo/img-resize/?photo=http://site.ru/1.jpg, где «http://site.ru/1.jpg» — путь к изображению.
Вот и всё. Для решения задачи нам потребовалось всего лишь 9 строк кода. Удачного вам кодинга и работающего кода. До следующего поста!
Рекомендуем посмотреть
Метки: php, программирование, сайт
Макс: Согласен. =) Не за что.
отличная статейка, автору +5))
Хорошая статья , мне помогла .
Отличный алгоритм по уменьшению!!! Все понятно, да еще и подробные комментарии к каждой строчке. Переделал твой пример в виде функции для GIF, JPEG, PNG, думал скопировать сюда — мало ли кому пригодится, да не стал — т.к. в коментарии кусок кода, наверное, не даст разместить.
Комментарии всё дадут разместить
А вот я — нет, но код не является спамом, поэтому пропущу его.
Тогда вот код:
function resizeImage ($source, $newWidth)
{ // start resizeImage ()
$sizeArr=GetImageSize ($source);
//Берём числовое значение ширины фотографии, которое мы получили в первой строке и записываем это число в переменную
$iw=$sizeArr[0];
//Проверяем, если размер ширины до которой мы хотим уменьшить ($newWidth), больше размера, загруженного пользователем фото, то уменьшть нет смысла, выход из функции
if ($newWidth >= $iw) return;
//Проделываем ту же операцию, что и в предыдущей строке, но только уже с высотой.
$ih=$sizeArr[1];
//Ширину фотографии делим на $newWidth т.к. на выходи мы хотим получить фото шириной в $newWidth пикселей. В результате получаем коэфициент соотношения ширины оригинала с будущей превьюшкой.
$koe=$iw/$newWidth;
//Делим высоту изображения на коэфициент, полученный в предыдущей строке, и округляем число до целого в большую сторону — в результате получаем высоту нового изображения.
$new_h=ceil ($ih/$koe);
//Определяем тип, загруженного пользователем изображения 1 = GIF, 2 = JPG, 3 = PNG
$type=$sizeArr[2];
//Создаём новое изображение из «старого». Основываясь на типе загруженного изображения пользователем, выбираем соответствующую функцию.
if ($type==1) $src=imagecreatefromgif ($source);
else
if ($type==2) $src=imagecreatefromjpeg ($source);
else
if ($type==3) $src= imagecreatefrompng ($source);
else
return;
//Создаём пустое изображение шириной в $newWidth пикселей и высотой, которую мы вычислили в предыдущей строке.
$dst=ImageCreateTrueColor ($newWidth, $new_h);
//Данная функция копирует прямоугольную часть изображения в другое изображение, плавно интерполируя пикселные значения таким образом, что, в частности, уменьшение размера изображения сохранит его чёткость и яркость.
ImageCopyResampled ($dst, $src, 0, 0, 0, 0, $newWidth, $new_h, ImageSX ($src), ImageSY ($src));
//Сохраняем полученное изображение в соответствуещем формате GIF, JPG или PNG
if ($type==1) imagegif ($dst, $source);
else
if ($type==2) imagejpeg ($dst, $source, 100);
else
if ($type==3) imagepng ($dst, $source, 0);
else
return;
} // end resizeImage ()
— Еще бы пример. как потом сохранить данное изображение.
Так оно же сохраняется в файл.
Попытаюсь прикрутить скрипт к ТОП 10 мудулю новостей на сайте
удачи в прикручивании
Спасибо, Илья.
Искал пол часа в инете эту страницу:)
Добавьте пожалуйста кэш по типу этого скрипта:
$image = ''; // в переменной $image будет храниться имя файла, который в данный момент обрабатывается
define ('CACHE_DIR','uploads/copy'); // директория для хранения кеша (она должна уже существовать)
include ('funcopy.php');
$name = CACHE_DIR.'/'.$image.'.jpg'; // имя превьюшки (последнее «.jpg» — не ошибка!)
// если кешированный эскиз уже существует, отдать его и завершить работу
if (file_exists ($name))
{
header ('Content-type: image/jpeg');
readfile ($name);
exit ();
}
// иначе — создаём новый эскиз
ob_start ();
$res = send_thumbnail ($image,200,150); // $res — результат создания эскиза (TRUE или FALSE)
$content = ob_get_contents (); // записываем в $content содержимое эскиза
if ($res && (@$fp = fopen ($name,'wb+'))) // если всё хорошо, создаём файлик с кешем и пишем туда содержимое
{
fputs ($fp,$content);
fclose ($fp);
ob_end_flush (); // выводим эскиз
}else
{
@ob_end_clean (); // очищаем буфер и рапортуем об ошибке
header ('Content-type: text/html'); // функция для создания preview отправляет заголовок Content-type: image/jpeg, а буферизация вывода заголовки пропускает
die ('Could not create preview! Reason: '.d_error ());
}
Ура!!!
всё)
Прикрутил, можете посмотреть результат:) на моём сайте
Только осталось решить проблемы с выводом в двиге.
Вверху над записями маленькие картинки — это оно?
Угу, где в самом центре jquery прокрутка.
Сейчас осталось оптимизировать под ie и запустить волну регистрации.
Всем удачи!
Ещё опубликую хак на dle сайтах
Ссылочку попозже дам:)
)))
Только хост реально глюченый.
Люди а не подскажите как сделать уменьшения изображения перед загрузкой на сервер??
уменьшить фото перед загрузкой не возможно. Однако, я понял, что вы хотите. Для этого вам надо взять пхп скрипт загрузки изображения на хостинг и передать из него переменную с именем загруженного файла, а затем уменьшить этим скриптом свежезагруженный файл.