• Мой Twitter
    @ilyazh: Наконец-то добрался до дома. Такая муть в универе. Всего 2 пары сегодня, но с перерывом в 4 часа....

PHP: пропорциональное уменьшение изображения

17 Авг 2009, Илья, 37 комментариев

Фух. Наконец-то появилось свободное время — завершил все заказы по верстке, написал с нуля небольшой веб сервис (о нём я расскажу позже. В конце августа или в начале сентября), а теперь напишу небольшой урок по php. Хотя в дальнейшем я буду публиковать новые уроки по программированию. Буду рассматривать свои «старые» скрипты, а также делиться опытом в «прямом эфире» — т.е. научился чему-либо, попробую научить и вас.

Сегодня я разберу скрипт своего старого музыкального портала, который я написал в далёком 2005 году, когда ещё не кто и не мечтал о верстке дивами и все верстали таблицами. =) Тогда наверно и не существовало html-верстальщиков — ибо один человек мог напсать с нуля статическую домашнюю страничку и гордиться этим. icon mrgreen PHP: пропорциональное уменьшение изображения Следовательно, мой сайт был сверстан таблицами и у меня появилась проблема. Поскольку любой пользователь могу добавить в галерею сайта фотографии, то фотографий в галереи было много и они были разного размера, но фотогалерея сайта была задумана так, чтобы фотографии размещались по 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 строк кода. Удачного вам кодинга и работающего кода. До следующего поста!

Рекомендуем посмотреть

Метки: , ,

37 комментариев

« Предыдущие комментарии Следующие комментарии »
  1. Макс: Согласен. =) Не за что.

  2. Сергей:

    отличная статейка, автору +5))

  3. Павел:

    Хорошая статья , мне помогла . :smile:

  4. Отличный алгоритм по уменьшению!!! Все понятно, да еще и подробные комментарии к каждой строчке. Переделал твой пример в виде функции для 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 ()

  5. Спасибо, Илья.

    Искал пол часа в инете эту страницу:) :grin:

    Добавьте пожалуйста кэш по типу этого скрипта:

    $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 ());

    }

  6. Ура!!!

    всё)

    Прикрутил, можете посмотреть результат:) на моём сайте

    Только осталось решить проблемы с выводом в двиге.

  7. Угу, где в самом центре jquery прокрутка. :grin:

    Сейчас осталось оптимизировать под ie и запустить волну регистрации.

    Всем удачи!

  8. Ещё опубликую хак на dle сайтах

    Ссылочку попозже дам:)

  9. Денис:

    Люди а не подскажите как сделать уменьшения изображения перед загрузкой на сервер??

    • Денис уменьшить фото перед загрузкой не возможно. Однако, я понял, что вы хотите. Для этого вам надо взять пхп скрипт загрузки изображения на хостинг и передать из него переменную с именем загруженного файла, а затем уменьшить этим скриптом свежезагруженный файл.

Добавить ответ

Следуй за мной!

Follow Me! Follow Me! Follow Me!

Популярные записи

  1. Убираем визуальные закладки Яндекс в Firefox 3.5
  2. Возвращаем поиск Google в Firefox 3.5
  3. Переносим настройки Mozilla, делаем бэкап.
  4. Запускаю социальную сеть
  5. Трансляция блога и раздача инвайтов.

Статистика


Реклама