Масштабирование изображений на PHP и GD
Сегодня очередной пост, который будет полезен начинающим PHP программистам. Я приведу пример простого класса для создания превьюшек изображений с помощью PHP и графической библиотеке GD.
Самая распространенная задача, при работе с изображениями — создание уменьшенной копии. Например для создания аватарок или превью фотографий и т.д. Напишем для этой задачи небольшой класс.
Сначала определим задачу: Во первых нам нужен класс, который будет работать с 3-мя популярными форматами изображений: jpeg, gif и png. Во вторых, при масштабировании должно сохраняться соотношение сторон.
-
/**
-
* Класс масштабирования изображении
-
*/
-
class image{
-
private $file; //Путь к файлу с исходным изображением
-
private $image; //Исходное изображение
-
private $image_new=false; //Изображение после масштабирования
-
-
/**
-
* Загрузка файла для обработки
-
*
-
* @param string $file путь к файлу
-
*/
-
public function __construct($file)
-
{
-
if(!file_exists($file)) return false;
-
-
//Получаем информацию о файле
-
list($width, $height, $image_type) = getimagesize($file);
-
-
//Создаем изображение из файла
-
switch ($image_type)
-
{
-
case 1: $this->image = imagecreatefromgif($file); break;
-
case 2: $this->image = imagecreatefromjpeg($file); break;
-
case 3: $this->image = imagecreatefrompng($file); break;
-
default: return ''; break;
-
}
-
$this->file=$file;
-
}
-
-
/**
-
* Масштабирует исходное изображение
-
*
-
* @param int $W Ширина
-
* @param int $H Высота
-
*/
-
public function resize($W, $H)
-
{
-
$this->image_new=false;
-
-
$X=ImageSX($this->image);
-
$Y=ImageSY($this->image);
-
-
-
$H_NEW=$Y;
-
$W_NEW=$X;
-
-
if($X>$W){
-
$W_NEW=$W;
-
$H_NEW=$W*$Y/$X;
-
}
-
-
if($H_NEW>$H){
-
$H_NEW=$H;
-
$W_NEW=$H*$X/$Y;
-
}
-
-
$H=(int)$H_NEW;
-
$W=(int)$W_NEW;
-
-
-
$this->image_new=imagecreatetruecolor($W,$H);
-
imagecopyresampled($this->image_new,$this->image,0,0,0,0,$W,$H,$X,$Y);
-
-
}
-
-
-
/**
-
* Сохранение файла
-
*
-
* @param string $file Путь к файлу (если не указан, записывает в исходный)
-
* @param int $qualiti Качество сжатие JPEG
-
*/
-
public function save($file=false, $qualiti=90)
-
{
-
if(!$file || $file==$this->file) {
-
$file=$this->file;
-
if(!$this->image_new) return true;
-
else ImageJpeg($this->image_new, $file, $qualiti);
-
}else{
-
if(!$this->image_new) copy($this->file, $file);
-
else ImageJpeg($this->image_new, $file, $qualiti);
-
}
-
}
-
}
И пример использования класса, создадим из файла myImage.jpeg две уменьшеные копии:
-
$image = new image('upload/myImage.jpeg');
-
$image->resize(20, 20);
-
$image->save('upload/mySmallImage.jpeg');
-
$image->resize(400, 300);
-
$image->save('upload/myBigImage.jpeg');
А почему сохраняем то только в jpg? По идее надо если исходная картинка gif, то сохранять в gif, если png — соответственно png. А тут получается независимо от исходной картинки на выходе имеем jpg.
И еще интересная отдельная тема — сохранение альфа-канала (прозрачности/полупрозрачности в png), а то я сталкивался — если просто
imagecreatefrompng
imagecreatetruecolor
imagecopyresampled
imagepng
то прозрачный фон превращается в непрозрачный
@VK
JPG на выходе — это дело вкуса. По мне, лучше и иметь на сервере все изображения в одном формате, это упрощает их массовую обработку (если потребуется).
А вот насчет альфа-канала в PNG — тема действительно интересная, спасибо Вам за нее. На досуге попробую найти решение.
А решение есть и очень простое, один из цветов делаем прозрачным:
Создание нового цвета и занесение его в палитру рисунка.
$white = imagecolorallocate($im, 255, 255, 255);
//$im — идентификатор изображения, заданный функцией imageCreate()
Определение цвета прозрачности.
imageColorTransparent($im, 255, 255, 255)
осталось вывести изображение…
Вот и всё!!!
з.ы.: если где то ошибся, прошу поправить)))
Спасибо огромное автору статьи — с первого раза все заработало, аж не ожидал, обычно приходится любой код, добытый таким образом править и править
А вот, как я дополнил страницу загрузки изображения (форму не буду публиковать — все легко) которым пользуюсь я (если интересно):
resize(400, 400);
$image->save($uploadfile);
/*вызываем успешно размещенную картинку, чтобы показать результат обработки */
echo «Картинка успешно сжата. Вот она, собсно:»;
// [-] МАСШТАБИРОВАНИЕ ЗАГРУЖЕННОГО ИЗОБРАЖЕНИЯ
?>
Резюмирую: конкретно данный скрипт позволяет загрузить максимально дозволенного настройками PHP на сервере размера оригинал картинки в папку img, выставить на нее права доступа 777, затем масштабирует картинку до размера одной из сторон не более 400 пикселей и перезаписывает исходный файл в директории img. И еще — запрещает загрузку файлов с кодом PHP (некая пассивная безопасность).
Если кому оказалось полезным — мне очень приятно. В случае чего, мастера, кидайте ботинки, люблю конструктивную критику — я ведь не волшебник, а только учусь
Ну вот, сидел, набирал, а код-то и не вставился полностью… Ну, если кому интересно, пишите сюда, поделюсь…
@Денис
Рад, что моя статья пригодилась.
А чтобы вставить код в текст комментария, нужно заменить знаки
Упс, спасибо за напоминание Итак, публикуюсь, и помоги мне великий WordPress на этот раз:
<?php
$subname = «Префикс к имени файла»;
// ТУТ ВСТАВЛЯЕМ КЛАСС, ПРЕДЛОЖЕННЫЙ АВТОРОМ
// ДАЛЕЕ ОСТАЛЬНОЙ КОД
/* тут запрещаем к загрузке файлы, содержащие php */
$blacklist = array(«.php», «.phtml», «.php3″, «.php4″);
foreach ($blacklist as $item)
{
if(preg_match(«/$item\$/i», $_FILES['userfile']['name']))
{
echo «Файлы, содержащие php-код запрещены к загрузке\n»;
exit;
}
}
/* укажем полный путь к директории загрузки (на примере Мастерхоста) Причем права на директорию нужно выставить 775 */
$uploaddir = ‘/home/uXXXXX/домен.ru/www/img/’;
/* извлекаем расширение файла */
$file_ext = strrchr(basename($_FILES['userfile']['name']), ‘.’);
/* собственно сам процесс загрузки через временную директорию домена */
$uploadfile = $uploaddir . $subname . $file_ext;
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile))
{
chmod($uploadfile,0777); /* выставляем права на картинку (можно и свои) */
echo «Изображение успешно загружено.\n»;
// [+] МАСШТАБИРОВАНИЕ ЗАГРУЖЕННОГО ИЗОБРАЖЕНИЯ (побитый мной скрипт автора)
$image = new image($uploadfile);
$image->resize(400, 400);
$image->save($uploadfile);
/*вызываем успешно размещенную картинку, чтобы показать результат обработки */
echo «Картинка успешно сжата. Вот она, собсно:<br><br><img src=\»img/» . $subname . $file_ext . «\»>»;
// [-] МАСШТАБИРОВАНИЕ ЗАГРУЖЕННОГО ИЗОБРАЖЕНИЯ
?>
Блин, Роман, прошу прощения, но предыдущий пост удаляй, что-то я невнимателен:
$subname = «Префикс к имени файла»;
// ТУТ ВСТАВЛЯЕМ КЛАСС, ПРЕДЛОЖЕННЫЙ АВТОРОМ
// ДАЛЕЕ ОСТАЛЬНОЙ КОД
/* тут запрещаем к загрузке файлы, содержащие php */
$blacklist = array(«.php», «.phtml», «.php3″, «.php4″);
foreach ($blacklist as $item)
{
if(preg_match(«/$item\$/i», $_FILES['userfile']['name']))
{
echo «Файлы, содержащие php-код запрещены к загрузке\n»;
exit;
}
}
/* укажем полный путь к директории загрузки (на примере Мастерхоста) Причем права на директорию нужно выставить 775 */
$uploaddir = ‘/home/uXXXXX/домен.ru/www/img/’;
/* извлекаем расширение файла */
$file_ext = strrchr(basename($_FILES['userfile']['name']), ‘.’);
/* собственно сам процесс загрузки через временную директорию домена */
$uploadfile = $uploaddir . $subname . $file_ext;
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile))
{
chmod($uploadfile,0777); /* выставляем права на картинку (можно и свои) */
echo «Изображение успешно загружено.\n»;
// [+] МАСШТАБИРОВАНИЕ ЗАГРУЖЕННОГО ИЗОБРАЖЕНИЯ (побитый мной скрипт автора)
$image = new image($uploadfile);
$image->resize(400, 400);
$image->save($uploadfile);
/*вызываем успешно размещенную картинку, чтобы показать результат обработки */
echo «Картинка успешно сжата. Вот она, собсно:
»;
// [-] МАСШТАБИРОВАНИЕ ЗАГРУЖЕННОГО ИЗОБРАЖЕНИЯ
?>
Вечер добрый. У меня есть вопрос по поводу контекстной рекламы у Вас на сайте. Вам не доводилось сталкиваться со случаями блокирования аккаунта администрацией гугла за как бы «накрутку»? Как защитить себя в этом случае?
@Stronzo
К счастью, с такой проблемой не сталкивался.
Есть хороший небольшой скрипт в тему — http://www.image-resizer.ru
Уменьшает по ширине и высоте, обрезает лишнее с краёв, приводит к одному размеру, кеширует… Рекомендую!