Изменение размера изображения средствами PHP
Постоянно нам приходится принимать от пользователей различные данные. Довольно часто в этих данных встречаются изображения, которые необходимо сохранить на сервере для дальнейшего использования. Для того чтобы все загруженные изображения одинаково вписывались в общий дизайн сайта, либо занимали меньше дискового пространства, нам необходимо изменять размеры изображения. Конечно, есть функции для проверки ширины и высоты, но согласитесь, будет некорректно сообщать пользователю, что изображение не подходит для вашего сайта.
На этот случай у меня есть один хороший класс под название SimpleImage, который позволяет довольно гибко изменять размеры изображения.
<?php
class SimpleImage {
var $image;
var $image_type;
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
if( $this->image_type == IMAGETYPE_JPEG ) {
$this->image = imagecreatefromjpeg($filename);
} elseif( $this->image_type == IMAGETYPE_GIF ) {
$this->image = imagecreatefromgif($filename);
} elseif( $this->image_type == IMAGETYPE_PNG ) {
$this->image = imagecreatefrompng($filename);
}
}
function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image,$filename,$compression);
} elseif( $image_type == IMAGETYPE_GIF ) {
imagegif($this->image,$filename);
} elseif( $image_type == IMAGETYPE_PNG ) {
imagepng($this->image,$filename);
}
if( $permissions != null) {
chmod($filename,$permissions);
}
}
function output($image_type=IMAGETYPE_JPEG) {
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image);
} elseif( $image_type == IMAGETYPE_GIF ) {
imagegif($this->image);
} elseif( $image_type == IMAGETYPE_PNG ) {
imagepng($this->image);
}
}
function getWidth() {
return imagesx($this->image);
}
function getHeight() {
return imagesy($this->image);
}
function resizeToHeight($height) {
$ratio = $height / $this->getHeight();
$width = $this->getWidth() * $ratio;
$this->resize($width,$height);
}
function resizeToWidth($width) {
$ratio = $width / $this->getWidth();
$height = $this->getheight() * $ratio;
$this->resize($width,$height);
}
function scale($scale) {
$width = $this->getWidth() * $scale/100;
$height = $this->getheight() * $scale/100;
$this->resize($width,$height);
}
function resize($width,$height) {
$new_image = imagecreatetruecolor($width, $height);
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
}
}
?>
Теперь после того как мы поместили данный файл класса SimpleImage к себе на сервер посмотрим как его можно использовать.
Следующий участок кода загрузит изображение image.jpg, изменить его ширину до 400 пикселей и высоту до 200 пикселей, а затем сохранит как image1.jpg.
<?php
include('classSimpleImage.php');
$image = new SimpleImage();
$image->load('image.jpg');
$image->resize(400, 200);
$image->save('image1.jpg');
?>
Если необходимо изменить размеры изображения, основываясь только на ширине и при этом сохранить его пропорции, то сценарий сам выберет необходимую высоту. Для этого необходимо использовать метод resizeToWidth.
<?php
include('classSimpleImage.php');
$image = new SimpleImage();
$image->load('image.jpg');
$image->resizeToWidth(250);
$image->save('image1.jpg');
?>
Возможно вы пожелаете изменить размер в процентном соотношении от его оригинала. Для этого существует метод scale, в качестве параметра которому передаются проценты.
<?php
include('classSimpleImage.php');
$image = new SimpleImage();
$image->load('image.jpg');
$image->scale(50);
$image->save('image1.jpg');
?>
У данного класса есть еще один очень полезный метод output, который позволяет выводить изображения прямо в браузер, без предварительного сохранения. Данный метод может быть очень полезен при создании миниатюр.
<?php
header('Content-Type: image/jpeg');
include('classSimpleImage.php');
$image = new SimpleImage();
$image->load('image.jpg');
$image->resizeToWidth(150);
$image->output();
?>
Автор данного класса Simon Jarvis, на своем сайте предлагает следующий пример для изменения размера изображения загруженного через форму.
<?php
if (isset($_POST['submit']) ) {
include('classSimpleImage.php');
$image = new SimpleImage();
$image->load($_FILES['uploaded_image']['tmp_name']);
$image->resizeToWidth(150);
$image->output();
}
else {
$form = '<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="uploaded_image" />
<input type="submit" name="submit" value="Upload" />
</form>';
echo $form;
}
Вот такой очень маленький, но довольно функциональный получился класс SimpleImage, который очень пригодиться любому разработчику.
Комментарии
Согласен, класс действительно функциональный, а использование интуитивно понятно.Самому как-то приходилось писать скрипт для загрузки и ресайза изображений, но не писал для него класс...PS. Можем обменяться постовыми, если желаете)
Спасибо. Помогла твоя статья.
Благодарю, хорошее решение.
Как-будто спижжено с WideImage Library
Утянул, спасибо
Спасибо!
буду ломать голову, спасибо, есть теперь над чем)
Спасибо. Только ваша статья помогла.
код может и фурычит, вот только include не фурычит, ругается что не может найти файл с классом хотя и адрес верный ввожу и сам файл работоспособный.
при подлючении в коде указан "SimpleImage.php", а в архиве файл с названием "classSimpleImage.php". Переименуйте файл или же допишите слово class в пути подключения скрипта =)
Спасибо! Исправил
Спасибо, очень помогла статья, особенно то как сохранить изображение)Действительно очень функциональный класс!
Никак не могу разобраться с выводом output! Нужны именно миниатюры фотографий, без сохранения.
Объясните, пожалуйста, как же вывести нашу миниатюру!
Отличная работа. Коллега. Классная инкапсуляция стандартный функций.
а это куда всовывать? "Retaining Transparency with PHP Image Resizing" http://www.white-hat-web-desig...
Спасибо большое! Отличный класс
Спасибо, хороший класс. Добавил в него свой метод, который вырезает из картинки эллипс - столкнулся с проблемой сохранения прозрачности. Сделал по умолчанию выходной формат PNG, добавил в метод load() строчки: imagealphablending($this->image,false); imagesavealpha($this->image,true); а в метод ellipse(): imagealphablending($im,true); - проблема решена. Следует учесть, что эти строки должны быть прописаны сразу после создания изображения.
Спасибо большое за отзыв! Очень полезная информация.
Я просто подумал что если делать ресайз изображения, в котором присутствуют прозрачные элементы, может возникнуть проблема, хотя не пробовал честно говоря)
Ребята, подскажите, куда вставлять эти строчки? Скрипт очень крутой, нужно сделать, чтоб фон прозрачный у png оставался...
Нашел немного редактированный класс, с ним все работает. Мало ли кому пригодится.:
Если изначально картинка уже маленькая(а мы не знаем), и мы ее ресайзим до большего размера, то сохраняется большая картинка в плохом качестве. А должно наверно просто оставлять как есть.
Большое спасибо! Очень помогло! Спасло много времени! )))
А если изображение вертикальное, а нужно сделать его горизонтальным, то есть вырезать из него кусок заданного размера?
Спасибо большое автору!!
Спасибо, то что искал))
Огромное спасибо!
Спасибо автору класса и автору статьи, очень помгло, хотел сам уже писать!
изображение ...путь изображения ... не может быть показано так как содержит ошибки, как исправить
Шикарно! Спасибо огромное! 2дня потратил на написание своего кода, но либо не загружал на сервер, либо загружал но не менял размер. Теперь всё работает :-)
большое спасибо, освоил работу с изображениями с помощью этого класса
Функция изминение двух сторон рисунка
Спасибо за класс, довольно понятно и просто все.
просьба подсказать что должно быть в файле upload.php на который ссылается форма, без него не работает.
Это и есть содержимое файла upload.php. Форма и обработчик в одном файле, это всеголишь в рамках примера.
все примеры работоспособны за исключением примера с формой, выдает след. сообщение:
Спс за оперативный ответ.
Есть необходимость уменьшать изображение при этом, чтобы качество было самым высоким.
Всегда использовал стандартное решение:
$size=GetImageSize ($uploadfile);
$src=ImageCreateFromJPEG ($uploadfile);
$iw=$size[0];
$ih=$size[1];
$koe=$iw/250;
$new_h=ceil ($ih/$koe);
$dst=ImageCreateTrueColor (250, $new_h);
ImageCopyResampled ($dst, $src, 0, 0, 0, 0, 250, $new_h, $iw, $ih);
ImageJPEG ($dst, $uploadfileS, 100);
Но как оказалось, что если уменьшить фото через фотошоп (cs6), то при одинаковых условиях в фотошопе уменьшенное фото имеет выше качество. Это заметно невооруженным глазом. Даже при том, что в функции ImageJPEG в третьем параметре стоит 100 %
Класс, который описан в статье как-то решает эту проблему или есть какие-то другие решения?
К сожалению не делал таких тестов, но вы всегда можете их сделать и поделиться результатом:)
Спасибо, хорошее описание на русском.
Все аккуратно, чисто и функционально.Спасибо!
Огромное СПАСИБО автору! Полезно!
ИМХО. Всё остальное - кому чего не хватает - уверен, каждый допишет лично.
Утянул.
Warning: imagejpeg(): Unable to open 'image1.jpg' for writing: Permission denied in /home/cloudtown/www/test/index.php on line 24
Выдает такую ошибку при использование
$image = new SimpleImage();
$image->load('image.jpg');
$image->resize(400, 200);
$image->save('image1.jpg');
Скорее всего у вас проблемы с правами на файл. Выполните в консоле:
Добрый день знатоки!
Ситуация такова, мне нужно сперва до определенной ширины пропорционально уменьшить входящее изображение, а потом отрезать от него фрагмент с левого верхнего угла. По отдельности imagecopyresampled - выполняет первую задачу, а imagecopy - вторую, но если обе функции в деле, то выполняется только вторая, как это можно решить?
Эта проблема связана с тем что вы всегда применяете операцию к исходному изображению. Что бы решить это, после первой операции imagecopyresampled() вам нужно обновить изображение объекта $this.
Пример:
Спасибо за отклик, но теперь у меня появляется только черный квадрат
Спасибо автору за статью!
Есть папка download в ней папка tmp.
При загрузке изображения загружаются в download,как сделать,чтобы они загружались в папку 'tmp'?
Если move_uploaded_file($temp,"tmp/".$name),то выдает ошибку и все равно сохраняет файлы в папку download.
Подскажите как решить вопрос!
Кому интересно, так же есть готовая функция, которую можно использовать для ресайзинга изображений.
Большое спасибо!!!!!
Спасибо! А вотермарки можно ставить?
К сожалению нельзя.
Вы можете добавлять водяные знаки точнее накладывать изображение как следует из документации по php
https://php.net/manual/en/image.examples-watermark.php
Еще полезно будет прикрутить EXIF - http://plutov.by/post/ffmpeg_exif_rotate
Подскажите пожалуйста где в этом коде изменяется размер картинки и как задать свой размер? тут размер выходит 146х168, я уже 2 часа сижу не могу понять как это работает, мне нужно ширину 200px высоту авто или 250px. Жду вашей помощи)
.Cпасибо большое, так гораздо проще
спасибо за статью. очень пригодился ваш класс
Не работает с большими изображениями (с цифровика)
Покажите реализацию данного класса
это код выводит:
не может быть показано, так как содержит ошибки
если использовать:
то все нормально, но как добавляешь include и вписываешь код выше, так сразу выдает ошибку
Прозрачность в png делает чёрным :(
Изумительно ... Просто восхитительно !!! Спасибо огромное !!!
Как мне указать путь куда сохранять изображения. К примеру: "../../photo-galery/min/qwerty.jpg"?
всё работает хорошо, но! фото начиная с 2 мегабайт не сжимает выдает ошибку
а если изображение более 8 мб то:
как можно исправить то? хотябы чтобы до 4мб сжимала
Да просто в php.ini на сервере надо поменять лимит, если не ошибаюсь там как раз стоит 2Mb. У меня на apache все работает после того как лимит повысил.
Автор, спасибо за скрипт. пол дня проискал, ставил разные и все работали через одно место. Этот единственный без проблем заработал. И работает довольно быстро, так как я использую в цикле и сразу обрабатывается до 30 картинок.
Благодарю за полезную информацию. Очень качественный пост.
Мало знаю о PHP и был очень удивлён, что этот код у меня сразу сработал, без обычных головоломок и без кучи потерянного времени на их выяснение.
что-то не очень код срабатывает если открыть картинку в PNG и сохранять в JPEG он ее тупо сохраняет в PNG не смотрять на то что по умолчанию JPEG
В JPEG так и не удалось вывести. Ошибки.