Автоматизируем уменьшение и обрезку изображений

Сегодня мы будем писать скрипт на PHP, который будет автоматически масштабировать и обрезать изображения.
Зачем это нужно?
Допустим, у вас есть 100 изображений, которые нужно уменьшить до 300 пикселей в ширину. Или сжать до размеров аватара (100 на 100, например) и урезать до квадрата. Или уменьшить вдвое. Или произвести любую другую манипуляцию с масштабом и обрезкой...
Можете сразу скачать исходники:

Функция масштабирования

Первой мы рассмотрим функцию масштабирования.
Код целиком:
<?php
function resize($file_input, $file_output, $w_o, $h_o, $percent = false) {
	list($w_i, $h_i, $type) = getimagesize($file_input);
	if (!$w_i || !$h_i) {
		echo 'Невозможно получить длину и ширину изображения';
		return;
        }
        $types = array('','gif','jpeg','png');
        $ext = $types[$type];
        if ($ext) {
    	        $func = 'imagecreatefrom'.$ext;
    	        $img = $func($file_input);
        } else {
    	        echo 'Некорректный формат файла';
		return;
        }
	if ($percent) {
		$w_o *= $w_i / 100;
		$h_o *= $h_i / 100;
	}
	if (!$h_o) $h_o = $w_o/($w_i/$h_i);
	if (!$w_o) $w_o = $h_o/($h_i/$w_i);

	$img_o = imagecreatetruecolor($w_o, $h_o);
	imagecopyresampled($img_o, $img, 0, 0, 0, 0, $w_o, $h_o, $w_i, $h_i);
	if ($type == 2) {
		return imagejpeg($img_o,$file_output,100);
	} else {
		$func = 'image'.$ext;
		return $func($img_o,$file_output);
	}
}
?>
Теперь разберём функцию по частям.
Вызов функции:
resize($file_input, $file_output, $w_o, $h_o, $percent = false);
где $file_input – исходный файл, $file_output – файл, в который мы будем сохранять готовое изображение, $w_o и $h_o – ширина и высота объекта соответственно, $percent – логическое выражение, определяющее, в чем измеряется длина – в пикселях (по умолчанию) или в процентах.

Получаем ширину, высоту и тип исходного изображения.
Если у нас это не получается, выводим сообщение об ошибке и выходим из функции.
list($w_i, $h_i, $type) = getimagesize($file_input);
if (!$w_i || !$h_i) {
    echo 'Невозможно получить длину и ширину изображения';
    return;
}
Тип мы получаем в формате числа: 1 – gif, 2 – jpeg, 3 – png.
Нам же нужно представить его в виде строки.
Если тип файла подходит, то запускаем функцию под названием imagecreatefrom + разрешение файла (например, imagecreatefromjpeg) с параметром исходного файла, если же нет – опять выводим ошибку.
$types = array('','gif','jpeg','png');
$ext = $types[$type];
if ($ext) {
    $func = 'imagecreatefrom'.$ext;
    $img = $func($file_input);
} else {
    echo 'Некорректный формат файла';
    return;
}
Теперь переходим к размерам будущего файла.
Переводим проценты в пиксели и определяем размер недостающей стороны (если необходимо).
if ($percent) {
	$w_o *= $w_i / 100;
	$h_o *= $h_i / 100;
} 
if (!$h_o) $h_o = $w_o/($w_i/$h_i);
if (!$w_o) $w_o = $h_o/($h_i/$w_i);
Создаём новое изображение и вставляем в него уменьшенный исходный файл.
Сохраняем во внешний файл.
Если сохраняем в jpeg, то дополнительно к первым двум параметрам указываем качество – число от 0 до 100, где 100 - максимально возможное качество.
Функция возвращает true, если запись в файл была выполнена успешно и false, если что-то пошло не так.
$img_o = imagecreatetruecolor($w_o, $h_o);
imagecopyresampled($img_o, $img, 0, 0, 0, 0, $w_o, $h_o, $w_i, $h_i);
if ($type == 2) {
	return imagejpeg($img_o,$file_output,100);
} else {
	$func = 'image'.$ext;
	return $func($img_o,$file_output);
}

Функция обрезки

Теперь функция обрезки.
<?php
function crop($file_input, $file_output, $crop = 'square',$percent = false) {
	list($w_i, $h_i, $type) = getimagesize($file_input);
	if (!$w_i || !$h_i) {
		echo 'Невозможно получить длину и ширину изображения';
		return;
        }
        $types = array('','gif','jpeg','png');
        $ext = $types[$type];
        if ($ext) {
    	        $func = 'imagecreatefrom'.$ext;
    	        $img = $func($file_input);
        } else {
    	        echo 'Некорректный формат файла';
		return;
        }
	if ($crop == 'square') {
		$min = $w_i;
		if ($w_i > $h_i) $min = $h_i;
		$w_o = $h_o = $min;
	} else {
		list($x_o, $y_o, $w_o, $h_o) = $crop;
		if ($percent) {
			$w_o *= $w_i / 100;
			$h_o *= $h_i / 100;
			$x_o *= $w_i / 100;
			$y_o *= $h_i / 100;
		}
    	        if ($w_o < 0) $w_o += $w_i;
	        $w_o -= $x_o;
	   	if ($h_o < 0) $h_o += $h_i;
		$h_o -= $y_o;
	}
	$img_o = imagecreatetruecolor($w_o, $h_o);
	imagecopy($img_o, $img, 0, 0, $x_o, $y_o, $w_o, $h_o);
	if ($type == 2) {
		return imagejpeg($img_o,$file_output,100);
	} else {
		$func = 'image'.$ext;
		return $func($img_o,$file_output);
	}
}
?>
Рассмотрим вызов функции:
crop($file_input, $file_output, $crop = 'square',$percent = false);
Параметры функции – исходный($file_input) и конечный($file_output) файл, переменная $crop, которая принимает координаты обрезки, а по умолчанию обрезает файл до квадрата, и, как и в первой функции, переменная $percent, которая принимает значение true или false.

Сначала пишем точно такой же код определения типа файла и его размеров, что и в первом случае. Надеюсь, объяснять его не потребуется.
list($w_i, $h_i, $type) = getimagesize($file_input);
if (!$w_i || !$h_i) {
	echo 'Невозможно получить длину и ширину изображения';
	return;
}
$types = array('','gif','jpeg','png');
$ext = $types[$type];
if ($ext) {
	$func = 'imagecreatefrom'.$ext;
	$img = $func($file_input);
} else {
	echo 'Некорректный формат файла';
	return;
}
Если координаты обрезки не заданы, то обрезаем изображение до формы квадрата. Как?
Очень просто: находим наименьшую сторону исходного изображения, и присваиваем её ширине и длине конечного изображения.
if ($crop == 'square') {
	$min = $w_i;
	if ($w_i > $h_i) $min = $h_i;
	$w_o = $h_o = $min;
} else {
	/*...*/		
}
Если же координаты существуют, то переносим их из массива в переменную и переводим проценты в пиксели (опять же, если это необходимо).
Получаем длину и ширину обрезаемой поверхности.
list($x_o, $y_o, $w_o, $h_o) = $crop;
if ($percent) {
	$w_o *= $w_i / 100;
	$h_o *= $h_i / 100;
	$x_o *= $w_i / 100;
	$y_o *= $h_i / 100;
}
if ($w_o < 0) $w_o += $w_i;
$w_o -= $x_o;
if ($h_o < 0) $h_o += $h_i;
$h_o -= $y_o;
Теперь создаём новый файл, копируем кусок изображения по координатам, которые только что получили, и сохраняем этот кусок в файл.
$img_o = imagecreatetruecolor($w_o, $h_o);
imagecopy($img_o, $img, 0, 0, $x_o, $y_o, $w_o, $h_o);
if ($type == 2) {
	return imagejpeg($img_o,$file_output,100);
} else {
	$func = 'image'.$ext;
	return $func($img_o,$file_output);
}
Вот и всё.

Чтобы не быть голословной, вот решение тех задач, которые я поставила в начале:

Уменьшаем 100 изображений до 300 px в ширину:
$files = array_slice(scandir('photos/'),2); // получаем файлы из директории
foreach ($files as $file) {
	resize($file, $file, 300, 0); // ширину не указываем – скрипт определит её сам
}
Уменьшение и обрезка аватара:
crop('big.jpg', 'crop.jpg');
resize('crop.jpg', 'avatar.jpg', 100, 100);


Уменьшаем изображение вдвое:
resize('big.jpg', 'small.jpg', 50, 50, true); 


Плюс ещё парочка задач:
Обрезаем изображение на 10 пикселей с каждой стороны:
crop('big.jpg', 'frame.jpg', array(10, 10, -10, -10));


Делим изображение на 4 равные части:
crop('big.jpeg', '1.jpeg', array(0, 0, 50, 50),true);
crop('big.jpeg', '2.jpeg', array(50, 0, 100, 50),true);
crop('big.jpeg', '3.jpeg', array(0, 50, 50, 100),true);
crop('big.jpeg', '4.jpeg', array(50, 50, 100, 100),true);

Вот и всё.


Комментарии

16 мая 2010, 12:53 (Ответить)
Интересный пример, попробую, спасибо.
23 мая 2010, 20:31 (Ответить)
А можно подробнее про подключение скрипта?
24 мая 2010, 17:28 (Ответить)
, в необходимом месте вставляете
include('/путь/к/скрипту/resize_crop.php'); 
затем вызываете нужную функцию
resize('big.jpg', 'small.jpg', 50, 50, true); 
// или
crop('big.jpg', 'crop.jpg');
31 мая 2010, 23:23 (Ответить)
Нина, скажи пожалуйста, а как сделать чтобы crop был не по левую сторону а строго по центру? я так понимаю надо узнать длинну и ширину изображения и поделить на 2?
2 июня 2010, 11:58 (Ответить)
, если необходимо обрезать изображение как на рисунке:

то нужно заменить в функции следующие строки
$min = $w_i;
if ($w_i > $h_i) $min = $h_i;

на эти:
if ($w_i > $h_i) {
$x_o = ($w_i - $h_i) / 2;
$min = $h_i;
} else {
$y_o = ($h_i - $w_i) / 2;
$min = $w_i;
}
5 июня 2010, 22:45 (Ответить)
Да, именно так и нужно было, спасибо.
5 июня 2010, 22:55 (Ответить)
Правда все равно что-то не правильно, если кропить 370х450px картинку, то он к правой стороне добавляет кусок заливки. С прямоугольными такого нету. т.е получается нужно еще проверку сделать на h_i > w_i
25 июля 2011, 17:32 (Ответить)
function crop($file_input, $crop = 'square',$percent = false) {
list($w_i, $h_i, $type) = getimagesize($file_input);
if (!$w_i || !$h_i)
return;

$types = array('','gif','jpeg','png');
$ext = $types[$type];
if ($ext) {
$func = 'imagecreatefrom'.$ext;
$img = $func($file_input);
} else
return;

if ($crop == 'square') {
$min = ($w_i > $h_i) ? $h_i : $w_i;
$w_o = $h_o = $min;
// Выравнивание по центру:
$x_o = intval(($w_i - $min) / 2);
$y_o = intval(($h_i - $min) / 2);
/*
// Выравнивание по правой стороне
$x_o = $w_i - $min;
// Выравнивание по низу
$y_o = $h_i - $min;
// Выравнивание по левой стороне
$x_o = 0;
// выравнивание по верху
$y_o = 0;
*/
} else {
list($x_o, $y_o, $w_o, $h_o) = $crop;
if ($percent) {
$w_o *= $w_i / 100;
$h_o *= $h_i / 100;
$x_o *= $w_i / 100;
$y_o *= $h_i / 100;
}
if ($w_o < 0)
$w_o += $w_i;
$w_o -= $x_o;
if ($h_o < 0)
$h_o += $h_i;
$h_o -= $y_o;
}
$img_o = imagecreatetruecolor($w_o, $h_o);
imagecopy($img_o, $img, 0, 0, $x_o, $y_o, $w_o, $h_o);

$temp_file = tempnam(sys_get_temp_dir() , 'crop');

if ($type == 2) {
$res = imagejpeg($img_o, $temp_file, 100);
} else {
$func = 'image'.$ext;
$res = $func($img_o, $temp_file);
}

if ($res)
return $temp_file;
else
return false;
}
11 июня 2010, 13:42 (Ответить)
Стоит заметить, что данный вариант не везде будет работать, так как требует значительно оперативной памяти.
Установленной на сервере 20Мб не хватает, приходится прибегать к ini_set('memory_limit', '35M');
35Мб это минимум того, что требуется!
Не везде на хостингах разрешен ini_set !
29 июня 2010, 23:57 (Ответить)
Если загружать и обрабатывать фотки по 4 мегабайта, то да нужно лимита побольше выставить, а если простенькие пикчи 1000х1000 в 500кб обычный хостер справится.
Также дополню, что еще нужно освобождать память ман: imagedestroy.
2 декабря 2010, 22:43 (Ответить)
А куда добавить imagedestroy для данного скрипта?
Видимо, слишком много оперативки сжирает вывод 12 фотографий на странице. :)
2 декабря 2010, 22:57 (Ответить)
Владимир, замените следующий код в скрипте
return imagejpeg($img_o,$file_output,100);
на этот:
imagejpeg($img_o,$file_output,100);
imagedestroy($img_o);
2 декабря 2010, 23:02 (Ответить)
Ого, оперативно. Спасибо!

А может из-за того, что у меня скрипт постоянно создает изображения при просмотре каталога, закончиться оперативная память на сервере?
2 декабря 2010, 23:11 (Ответить)
Наверняка может закончиться.
Лучше было бы генерировать изображение один раз и сохранять его, и в последующие разы обращаться уже к нему.
27 июля 2010, 10:52 (Ответить)
Вот когда обрабатываю одну картинку - скрипт работает отлично, а вот когда запускаю в цикле обработать кучу картинок он почему-то каряво режит. Мне необходимо обрезать все картинки из папки на сервере на 7 px снизу!

Как это лучше сделать?!
27 июля 2010, 11:15 (Ответить)
, без исходников сказать сложно.
Можно посмотреть код, в котором вы запускаете цикл для обрезки?
2 августа 2010, 15:25 (Ответить)
Спасибо за скрипт.
Скажите, как уменьшить прямоугольное изображение до определенного размера (например до 600px по длинной стороне)
3 августа 2010, 15:31 (Ответить)
, если вам необходимо обрезать изображение по _любой_ стороне, то можно использовать следующий код:
list($temp_w, $temp_h) = getimagesize('1.jpg'); // путь к картинке
$max = 600; // максимальный размер стороны
$h = $w = 0;
if ($temp_w < $temp_h) { // сравниваем размеры
$h = $max;
} else {
$w = $max;
}
resize('1.jpg', 'output.jpg', $w, $h); // вызываем основную функцию

А если сторона известна, то тогда всё будет ещё проще:
resize('1.jpg', 'output.jpg', 600, 0); 

либо
resize('1.jpg', 'output.jpg', 0, 600); 
23 августа 2010, 1:09 (Ответить)
Очень странно... crop отказывается обрезать фото, хотя функция ресайза замечательно масштабирует.
23 августа 2010, 13:18 (Ответить)
, можно пример неработающего crop'a?
23 августа 2010, 23:09 (Ответить)
Да, собственно сделал, как и указано в примере...может только по невнимательности что то пропустил...
в свой php файл вставил функцию crop и resize
В другой функции этого же файла:


$photo = $_FILES['filename']['name']."";
$photo_sm = preg_replace("/([a-zA-Z_\-0-9]*).([a-zA-Z]{3,4})/","\\1_sm.jpg","$photo");
resize($photo, $photo_sm, 0, 100);
crop('$photo_sm', '$photo_sm');

То есть с помощью регулярного выражения я добавляю к имени файла "_sm". Функция resize как и задумано изменяет размер. В результате после выполнения кода в папке лежит оригинальный файл 123.jpg и уменьшенный файл 123_sm.jpg , но уменьшенный файл не обрезан...
Моге на электронку скинуть полный код странички...это модуль antislaed
23 августа 2010, 23:24 (Ответить)
спасибо за ответ...
ошибку нашел сам... как и предполагал из-за невнимательности...
в строке crop('$photo_sm', '$photo_sm');
убрал кавычки crop($photo_sm, $photo_sm); и заработало. :)
24 августа 2010, 11:42 (Ответить)
, пожалуйста.
Кстати, если бы кавычки были двойными, то всё работало бы нормально.
9 сентября 2010, 21:03 (Ответить)
классный скрипт.
Но никак не могу понять, как мне получить превьюшку 130х195...?
т.е Не квадратную....
9 сентября 2010, 22:43 (Ответить)
, а какой функцией вы собираетесь пользоваться - crop или resize?
9 сентября 2010, 23:34 (Ответить)
хороший вопрос :)
фотография может быть любого размера, а превьюшка должна получиться вертикальной 130 на 195
я думал сначала делать ресайз (0,195), а потом кроп (130,195)
10 сентября 2010, 22:37 (Ответить)
, вот работающий код для того, что вам нужно:
        list($w, $h) = getimagesize('image.jpg'); // получаем размеры изображения
if ($w < $h) { // если ширина меньше высоты
resize('image.jpg','temp.jpg',130,0); // уменьшаем по ширине
} else { // иначе
resize('image.jpg','temp.jpg',0,195); //уменьшаем по высоте
}
crop('temp.jpg','thumb.jpg',array(0,0,130,195)); // и обрезаем
12 сентября 2010, 23:30 (Ответить)
Спасибо!
27 марта 2011, 19:10 (Ответить)
Возникла одна ошибка при таком действии, когда картинка квадратная, то он уменьшает, допустим, по ширине,а после обрезания, пустой кусок заливает черным, ну вообщем на практике более ясно будет. Решение такое:

просто добавляем еще одно условие

elseif($w==$h){
resize('image.jpg','temp.jpg',130,false);
}
И тогда код будет выглядеть следующим образом:

list($w, $h) = getimagesize('image.jpg'); // получаем размеры изображения
if ($w < $h) { // если ширина меньше высоты
resize('image.jpg','temp.jpg',130,0); // уменьшаем по ширине
}
elseif($w==$h){// если изображение является квадратом.
resize('image.jpg','temp.jpg',130,false);// уменьшаем пропорционально по ширине.
}
else { // иначе
resize('image.jpg','temp.jpg',0,195); //уменьшаем по высоте
}
crop('temp.jpg','thumb.jpg',array(0,0,130,195)); // и обрезаем

И спасибо за функции, очень пригодились. Правда стоило бы все эти решения, которые указаны в комментариях, вписать в саму статью, так как destroy изображения как не крути нужно, ведь без этого память засоряется. Ну и остальное добавить тоже следовало бы.
22 сентября 2010, 18:18 (Ответить)
Скопировал код, вставил в php файл и разместил на сайте, белый лист. Как его запустить то ??
23 сентября 2010, 17:16 (Ответить)
Vovec, запустить его очень просто - в конец файла добавить функцию resize или функцию crop с теми параметрами, которые вам необходимы:
crop('исходный файл.jpeg','изменённый файл.jpeg');
resize('изменённый файл.jpeg','конечный файл.jpeg',200,200);
Вышеприведённый код, например, обрезает изображения до размера квадрата и уменьшает до 200 px по ширине и длине.
17 октября 2010, 14:53 (Ответить)
Что бы сохранить прозрачность у png изображений при обрезке(и ресайзе) - необходимо добавить код после:
$img_o = imagecreatetruecolor($w_o, $h_o);

добавить:
if ($type == 3) {
	imagesavealpha($img_o, true);
	$trans_colour = imagecolorallocatealpha($img_o, 0, 0, 0, 127);
	imagefill($img_o, 0, 0, $trans_colour);
}
20 октября 2010, 10:35 (Ответить)
Medic84, спасибо.
Я добавлю этот код в статью.
18 февраля 2011, 13:04 (Ответить)
> imagecolorallocatealpha($img_o, 0, 0, 0, 127);

а почему черным заливается, а не белым?
23 марта 2011, 12:26 (Ответить)
Потому что цвет RGB 0, 0, 0 дан черным.
Измени imagecolorallocatealpha($img_o, 0, 0, 0, 127);

на imagecolorallocatealpha($img_o, 255, 255, 255, 127);
29 октября 2010, 21:02 (Ответить)
Помогите пожалуйста с интеграцией кода, есть у меня скрипт-обработчик который загружает файл в директорию, вот он:

Что требуется, нужно интегрировать в него функцию resize, crop что бы прежде чем файл сохранится в папке, нужно его обрезать по центру относительно всех сторон и сжимался до формата 150х150. Т.е размер загружаемого файла будет любым, а сохранятся он должен в формате 150х150. И ещё вопрос правда не по теме, но все же, как отсортировать загружаемые файлы, ну что бы загружались только png, jpg, gif. За ранее спасибо, а вообще автору спасибо за скрипт!
29 октября 2010, 21:45 (Ответить)
Hard, если не получается вставить код, залейте его сюда: pastebin.com или pastebin.ru и дайте на него ссылку в комментарии.
29 октября 2010, 21:55 (Ответить)
Вот залил код pastebin.com/bMeas2Zq что нужно сделать описал в сообщение выше
29 октября 2010, 23:15 (Ответить)
Hard, вот код, который нужно добавить после вашего:
list($w, $h) = getimagesize($uploadfile); // получаем размеры
$x = $y = 0;  
if ($w > $h) { // если ширина больше длины
	$x = ($w - $h) / 2; // вычисляем начало 
	$w = $h + $x; // и конец координат
} else { // иначе
	$y = ($h - $w) / 2; // делаем тоже самое 
	$h = $w + $y; // для высоты
}
crop($uploadfile,$uploadfile,array($x,$y,$w,$h)); // запускаем функцию обрезки с массивом координат
resize($uploadfile,$uploadfile,150,150); // запускаем функцию масштабирования

Насчет того, чтобы загружались только изображения... Способов много, начиная от проверки разрешения файла и заканчивая MIME типами, но самый простой вариант, по моему мнению, следующий:
 if (getimagesize('файл.джипег')) {
	// работаем с изображением
} else {
	// это точно не изображение! удаляем.
}

Здесь мы пробуем получить размеры изображения. Если размеров нет, значит, это не изображение.
30 октября 2010, 0:01 (Ответить)
Огромное спасибо все работает, блог вообще супер, подписываюсь на rss:)
30 октября 2010, 1:30 (Ответить)
А ещё такой момент, хочу сделать что бы имя загруженной картинки было уникальным, типо *******_имя.тип , где ****** - это случайное значение можно сделать через mt_rand, а имя.тип это исходные данный файла, но вот чет никак не соображу как это приспособить к скрипту.

P.S Сорь за назойливость, только недавно приступил к изучению php.
30 октября 2010, 9:02 (Ответить)
Hard, сделать это очень просто. В вашем скрипте замените строку
$uploadfile = $uploaddir.basename($_FILES['myfile']['name']);

на строку
$uploadfile = $uploaddir.mt_rand().'_'.basename($_FILES['myfile']['name']);

Теперь переменная $uploadfile будет выглядеть так: ../../../uploads/[случайное число]_file.jpeg.

P. S. Не надо извиняться, все мы ещё учимся ;)
9 апреля, 18:57 (Ответить)
И мне очень помог этот код! Спасибо!
9 ноября 2010, 12:38 (Ответить)
Если не сложно помочь ещё с одним кодом, вот есть код вот он pastebin.com/5FsaRC3n который загружает картинку на сервер, нужно что бы получалось сжатое и обрезанное изображение 150х150 но не пойму куда че поставить и как сделать что б работало)
9 ноября 2010, 17:28 (Ответить)
Hard, замените эту часть вашего кода
if ($width > $sw || $height > $sh) {
	$new = imagecreatetruecolor(150,150);
	if ($data['mime'] == 'image/jpeg' || $data['mime'] == 'image/jpg') {
		$old = imagecreatefromjpeg($_FILES['image']['tmp_name']);
		imagejpeg($old,$_FILES['image']['tmp_name'],100);
	} else {						
		$old = imagecreatefromgif($_FILES['image']['tmp_name']);
		imagegif($new,$_FILES['image']['tmp_name']);
	}
}

на следующую:
if ($width > $sw || $height > $sh) {
	crop($_FILES['image']['tmp_name'], $_FILES['image']['tmp_name']);
	resize($_FILES['image']['tmp_name'], $_FILES['image']['tmp_name'], 150, 150);
}
9 ноября 2010, 19:04 (Ответить)
Опять спасибо, все работает) Снова выручаешь...
11 марта 2011, 15:58 (Ответить)
и мне этот кусочек понадобился=) тока чуть чуть подругому
16 ноября 2010, 11:19 (Ответить)
Хорошие функции.

А как мне сделать обрезку изображения по вертикали не снизу а сверху?

Есть вертикальная картинка произвольного размера, я ее уменьшаю до 300px.
resize($bigimage,'temp.jpg',300,0);

и потом привожу к виду 300x200px
crop('temp.jpg',$smallimage,array(0,0,300,200));

Она орезается снизу. А нужно сверху!
17 ноября 2010, 19:42 (Ответить)
Scotch, самый простой вариант:
resize($bigimage,'temp.jpg',300,0);
$size = getimagesize('temp.jpg'); // получаем размеры промежуточного изображения
crop('temp.jpg',$smallimage,array(0, $size[1] - 200, 300, $size[1])); 
19 ноября 2010, 4:22 (Ответить)
Было бы очень хорошо если бы вы сделали наглядный пример с формой для загрузки resize (); и crop (); для 50x50px и 100x100px. Код действительно хороший. И сайт радует уникальными статьями.
19 ноября 2010, 9:06 (Ответить)
btcorp, спасибо!
В скором времени постараюсь написать.
19 ноября 2010, 14:33 (Ответить)
И вам благодарен.
23 ноября 2010, 10:36 (Ответить)
Хороший пример, но вот с прозрачными gif что то не работает. Подскажите что делать.
25 ноября 2010, 21:52 (Ответить)
Куда именно вставлять скрипт масштабирования ?
Распишите установку
2 декабря 2010, 17:00 (Ответить)
Гость, подключайте функцию там, где вам это необходимо. Например:
// код загрузки изображения
function resize($file_input, $file_output, $w_o, $h_o, $percent = false) {
	// код функции
}
resize('загруженное_изображение.jpg', 'avatar.jpg', 100, 100);
28 ноября 2010, 3:39 (Ответить)
Здравствуйте.
Так и не смог понять, как сделать:
1. Загрузили оригинал. Обрезали его до ширины 1024рх, до высоты 768рх. Если размеры картинки меньше чем 1024х768, то ничего не делаем. Сохранили.
2. Обрезали до квадрата.
3. Уменьшили эту квадратную картинку до 150х150. Сохранили в папке /small с тем-же именем.
2 декабря 2010, 17:16 (Ответить)
Александр, эту задачу можно решить следующим образом:
$file = '1.jpg'; // имя загружаемого файла
list($w, $h) = getimagesize($file); // получаем размеры
if ($w > 1024) crop($file,$file,array(0,0,1024,$h)); // если ширина больше максимума
if ($h > 768) crop($file,$file,array(0,0,$w,768));// если длина больше максимума
crop($file,$file); // обрезаем до квадрата
resize($file,'small/'.$file,150,150); // уменьшаем и сохраняем в папке small.
11 декабря 2010, 20:54 (Ответить)
А если изображение 50х50, то что будет ?
12 декабря 2010, 17:07 (Ответить)
Подскажите пожалуйста! Как передать картинку из формы, чтоб потом из нее создать 3 изображения.
Оригинал, квадрат и иконку? Затем эти картинки загрузить на сервер и добавить путь каждой картинки в базу MySQL?!
Сижу вторые сутки мучаюсь!
Спасибо!
12 декабря 2010, 23:21 (Ответить)
Странный все-таки ресиз
если изображение меньше заданного, то оно увеличивается ?
И как выводить функцию ? Здесь не написано
Или
"crop('big.jpg', 'crop.jpg');
resize('crop.jpg', 'avatar.jpg', 100, 100);"
это и есть вывод функции ?
17 декабря 2010, 15:53 (Ответить)
Ага именно так, однако если у тебя скрипт который выполняет изменение картинки находится не в той же директории что и big.jpg, то надо в этом параметре выводить не название имя файло, а переменную с полным путём к файло, например

$big = $_SERVER['DOCUMENT_ROOT']."/путь_к_файло/имя_файло.расширение_файло";
crop('$big', '$crop');
19 декабря 2010, 21:09 (Ответить)
Вот уже третий день в поисках какой нибудь информации как сделать закругленные углы при помощи PHP, AJAX не подходит... Может можно как то закруглять углы при загрузке. Немного не по теме но уже не знаю куда обратится... За ранее спасибо..
24 декабря 2010, 14:53 (Ответить)
А если нужно сделать изображение таким образом:
1. изменить размер по БОЛЬШЕЙ стороне до 100 px
2. затем добавить белое поле снизу и сверху до квадрата
чтобы получить 100х100 ?
16 января 2011, 23:54 (Ответить)
Подскажите как передать картинку из формы, обрезать, а затем залить на сервер?
Что-то не выходит обработать картинку.
На сервер закачивается, а вот ресайз и кроп ошибят!
За ранее спасибо...
27 января 2011, 18:35 (Ответить)
Дмитрий, на следующей неделе постараюсь выложить урок по отправке картинок на сервер с последующим масштабированием.

Возможно, вы выложите код, с которым работаете на pastebin? Так мне проще будет понять, что именно у вас не работает.
30 января 2011, 1:19 (Ответить)
Как сделать, чтобы при загрузке через форму были созданы две картинки (400 x 350) и (200 х 160), исходные картинки могут быть произвольно размера
5 февраля 2011, 19:46 (Ответить)
Класс полезный, написан хорошо.
Но мне не очень нравится, что формат входного файла определяется через его расширение - это, IMHO, не есть гут.
Во первых не безопасно, а во вторых можно пролететь - я встречал старенькие CMS и фреймворки, где все файлы для унификации доступа обзывались .gif вне зависимости от формата.
5 февраля 2011, 19:52 (Ответить)
Хм..
В первый раз невнимательно посмотрел - сорри... ;)
Мне показалось, что анализируется расширение файла, а у Вас аналогичная схема, просто еще идет отсечение прочих форматов, кроме трех основных...
9 февраля 2011, 18:36 (Ответить)
Код хороший, но меня интересует можно ли как-то сделать resize анимации (*. gif)?
9 февраля 2011, 19:04 (Ответить)
btcorp, средствами GD, на которой работают мои функции - этого не сделаешь, при ресайзе будут изменён только первый кадр.
Посмотрите в сторону ImageMagick, а именно этот материал: snippets.pp.ru/article/151
9 февраля 2011, 21:41 (Ответить)
Спасибо.
9 февраля 2011, 21:51 (Ответить)
Есть идея! Было бы вообще супер если бы на базе ВАШИХ функций сделали статью по "Jcrop - Jquery upload Crop" очень полезная вещь. Вложил файлы с плагином в архив.
bigtorrent-ua.com/jquery_upload_crop.zip
9 февраля 2011, 21:54 (Ответить)
Я пробовал сделать но не получается :(
PS: Архив можно скачать в течение 5-дней
9 марта 2011, 0:59 (Ответить)
Большое спасибо за пример, очень полезно. Наконец-то я смог реализовать свои задумки :)
15 марта 2011, 23:38 (Ответить)
Хороший и удобный скрипт обработки изображений. Главной прост, все понятно и разжевано. Долго искал такой простой, перерыл много аналогов, в том числе и забугровых.
Спасибо!
16 марта 2011, 16:13 (Ответить)
кто нить работал с плагином jquery imageareaselection?
odyniec.net/projects/imgareaselect/examples.html

я спрашиваю потому что там можно наводить на картинку как тебе надо и передавать через пост координаты которые можно вставить в
crop('big.jpg', 'frame.jpg', array(10, 10, -10, -10));
проблема в том что именно в примере где отправляются
данные через пост нету ограничения по выделению , но он есть в других примерах ,но у меня почему то не получаеться их соединить , помогите плиз
а плагин мне ваш нравится
тока хотел сказать вроде данные после загрузки надо удалять чтобы память не загружать
17 марта 2011, 12:20 (Ответить)
а как создать копию загруженого файла , а потом копию уменьшить
у меня идет код такой подскажите как и когда создать копию изображения

$name = $_FILES['upload']['name'];
$temp = $_FILES['upload']['tmp_name'];

move_uploaded_file ($temp,"avatar/$name");
$way = "avatar/$name";
echo "";
1 апреля 2011, 15:25 (Ответить)
Большое СПАСИБО автору очень помогло.
$crop == 'square' оказалось достаточно))
6 мая 2011, 15:57 (Ответить)
У меня не работает (((


И ничего ((( Загружается только оригинальный файл, а ничего не ресайзится ((
6 мая 2011, 15:59 (Ответить)
Вот код - pastebin.com/JbF23jrQ

З.Ы. Резать весь код, размещенный в тегах пхп это кощунство )))
6 мая 2011, 16:34 (Ответить)
Гыг, пока маялся тут, все заработало )))

Нина, большое спасибо за код. Не каждый день встретишь столь юную девушку-программиста *реверанс*
6 мая 2011, 19:10 (Ответить)
Рада, что у вас всё само собой разрешилось :)
Если бы и все остальные проблемы разрешались так легко...
13 мая 2011, 15:48 (Ответить)
Просьба огромная подскажите что куда подключать,Вот форма отправки








A это php обработчик он сохраняет фото


Мне надо чтобы большие фото уменьшились (не обрезались) при загрузке а фото которые подходят по размеру такие и оставались подскажите что делать?
13 мая 2011, 23:51 (Ответить)
Вот код pastebin.com/uE0GvQaD
14 мая 2011, 23:45 (Ответить)
Кто нибудь подскажите насчёт кода плиз:))))
21 мая 2011, 0:21 (Ответить)
Кто нибудь ответьте на счёт кода
30 мая 2011, 14:28 (Ответить)
Красава, крутой пример, очень помог в работе
30 мая 2011, 21:42 (Ответить)
еще раз мега респект автору, молодец что в универ не пошла, если бы не армия, тоже бы туда ни ногой
5 июня 2011, 23:56 (Ответить)
Большое спасибо за столь полезные функции! =)
3 августа 2011, 11:02 (Ответить)
Автору респект. Спасибо за статью.
26 августа 2011, 11:57 (Ответить)
При манипуляциями с изображением у него в обрезанных областях получается чёрный фон. Как задать другой цвет?
26 августа 2011, 12:11 (Ответить)
В crop();

Сделал:

$trans_colour = imagecolorallocate($img_o, 255, 0, 0);
imagefill($img_o, 0, 0, $trans_colour);

Перед:

imagecopy($img_o, $img, 0, 0, $x_o, $y_o, $w_o, $h_o);

Но всё равно чёрная полоса, вместо красной.
26 августа 2011, 12:46 (Ответить)
Надо изменить эту сроку:

imagecopy($img_o, $img, 0, 0, 0, 0, $w_i, $h_i);
30 августа 2011, 16:36 (Ответить)
А как сделать так чтобы у любой картинки обрезалась полоса снизу на 20px. Просто там водяная марка которую нужно обрезать.
25 сентября 2011, 7:56 (Ответить)
зхдравствуйте, надо обрезать изображение по координатам )
можете подсказать, почему у меня не создается обрезанное изображение ? если выполнить скрипт второй раз, то он выдает ошибку:
fatal error^ cannot redeclare crop () (previously declared in (1): eval()'d code8) in (1): eval()'d code on line 26
а при компиляции никаких ошибок не выдает )
что это за ошибка и почему не создавется новое изображение ?
заранее благодарен )
25 сентября 2011, 19:04 (Ответить)
Никита, в вашем скрипте код функции crop встречается 2 раза. В тексте ошибке говорится о том, что её нельзя переопределить, поскольку она уже была объявлена раньше. Уберите один из повторов и спокойно работайте дальше :)
25 сентября 2011, 20:16 (Ответить)
большое спасибо, я немного ступил )
еще вопросик: а можно ли обрезать изображение и вывести ео в браузер, не сохраняя его на диске ? то я в пхп еще не очень разбираюсь )
10 октября 2011, 16:40 (Ответить)
здравствуйте у меня вопрос мне надо изображенbя обрезать до 200/700 по цетру подскажите пожалуйста
как это сделать?
10 октября 2011, 21:37 (Ответить)
Появилась проблема, при обрезке изображения примерно 200 x 500, скрипт обрезает верхнюю и нижнюю часть, на таких изображениях верхнюю часть необходимо сохранить, подскажите пожалуйста какие строки в коде изменить
11 октября 2011, 16:46 (Ответить)
подскажите пожалуйста как вы обрезаете 200х500
просто мне нужно 200х700
28 октября 2011, 0:48 (Ответить)
Вот с какой проблемой столкнулся.

Заливка фоток ... сейчас же все модные, с 7-10-15-25 мегапикселками ходят.

фотография... 3000*2000 пикселей. Когда делаем imagecreatefromjpeg, то на сервере почему-то не отрабатывается, так как, насколько я понял, шарясь по сети, что при этом выедается памяти 3000*2000*24=144 Мб (при том, что картинка может весить 600Кб-1Мб)
как можно обойти, не меняя размер выделяемой памяти? как-то можно, на сайте есть двиг, который заливается эти картинки, но не могу в коде найти , где он это делает (двиг писал какой-то псих, впервые такую технологию вижу, но это не главное)
2 ноября 2011, 0:28 (Ответить)
У меня следующая проблемка(
Есть интернет магазин на котором при заливке в каталог товаров оно предлогает вставить три картинки большую,маленькую и среднюю,но размеры вы должны обрезать вручную,что крайне не удобно.Нужно чтобы масштабирование картинки происходило автоматически.
вот кусочек которые походу отвечает за данные о залитом изображении:
....
function GetPictureSize( $filename )
{
$size_info=getimagesize("./products_pictures/".$filename);
resize($file_input, $file_output, $w_o, $h_o, $percent = false);
return ((string)($size_info[0] + 40 )).", ".((string)($size_info[1] + 40 ));
}
....
А вот скрипт который бы нужно туда вставить:
function resize($file_input, $file_output, $w_o, $h_o, $percent = false)
{
list($w_i, $h_i, $type) = getimagesize($file_input);
if (!$w_i || !$h_i) {
echo 'Невозможно получить длину и ширину изображения';
return;
}
$types = array('','gif','jpeg','png');
$ext = $types[$type];
if ($ext) {
$func = 'imagecreatefrom'.$ext;
$img = $func($file_input);
} else {
echo 'Некорректный формат файла';
return;
}
if ($percent) {
$w_o *= $w_i / 100;
$h_o *= $h_i / 100;
}
if (!$h_o) $h_o = $w_o/($w_i/$h_i);
if (!$w_o) $w_o = $h_o/($h_i/$w_i);
$img_o = imagecreatetruecolor($w_o, $h_o);
imagecopyresampled($img_o, $img, 0, 0, 0, 0, $w_o, $h_o, $w_i, $h_i);
if ($type == 2) {
return imagejpeg($img_o,$file_output,100);
} else {
$func = 'image'.$ext;
return $func($img_o,$file_output);
}
}

простая замена кусочка кода не катит выбивает ошибку,подмена кусочков кода тоже не работает(просто не реагирует).
Добавлено 13 минут назад
моё знание PHP так на троечку пока,поэтому если нормально обьяснить то впринцыпи могу попробовать понять :)
2 ноября 2011, 19:32 (Ответить)
Спасибо, Нина :)
Хороший скрипт.
Как раз собирался написать скрипт для сведения аватаров к одинаковым размерам. Для примера очень даже пригодился.
5 ноября 2011, 0:50 (Ответить)
Здравствуйте)
У меня проблемка( Можете помочь?
Мне нужна чтоб при загрузки большой картинки на сервер она сжималась и меняла ширину и высоту где-то 200 на 200, пожалуйста помоги.
Код загрузки файла:

//------------------------










//------------------------
5 ноября 2011, 0:51 (Ответить)
А куда мне код кинуть?
5 ноября 2011, 1:26 (Ответить)
if ($_FILES["filename"]["size"] > 1024*3*1024)
{
echo ("Размер файла превышает три мегабайта");
exit;
}
// Проверяем загружен ли файл (is_uploaded_file -- Определяет, был ли файл загружен при помощи HTTP POST)
if(is_uploaded_file($_FILES["filename"]["tmp_name"]))
{
// Если файл загружен успешно, перемещаем его
// из временной директории в конечную
// move_uploaded_file -- Перемещает загруженный файл в новое место
move_uploaded_file($_FILES["filename"]["tmp_name"], "img/".$_FILES["filename"]["name"]);
} else {
echo("Ошибка загрузки файла");
}
11 ноября 2011, 21:10 (Ответить)
если ты этого не знаешь,значит тебе это не нужно
16 ноября 2011, 22:33 (Ответить)
Мне это нужно!!!
Тут я так понял помогают.
16 ноября 2011, 22:37 (Ответить)
recens
Мне нужна Ваша помощ.
2 декабря 2011, 17:00 (Ответить)
Спасибо огромной за скрипт. Отлично, отлично, отлично!!!
14 января, 15:00 (Ответить)
Спасибо Нина. Очень хороший скрипт. Всё четко и понятно.
19 января, 6:09 (Ответить)
Здравствуйте. Можно ли этот код прикрутить к выбору скачиваемого размера картинки? Например, у меня есть сайт обоев на компьютер, мне надо дать пользователям выбор, чтобы они могли скачать картинки себе с разными разрешениями. К примеру картинка имеет разрешение 1920х1080, и предоставляется выбор: 1600х1200, 1280х1024 и т.д. Или можете мне посоветовать другой пример или скрипт, чтобы много ресурсов не требовал, а то как я понял ваш пример много оперативы потребляет, если пользователи будут по много картинок вырезать, то довольно таки ощуттмая нагрузка получится. Очень нужно давно ищу такую функцию, помогите!
28 января, 22:29 (Ответить)
отличный выход если картинка горизонтальная как на этой картинге.

recens.ru/upload/resize/crop.png

А если картинка вертикальная, как сделать кроп по центру, подскажите пожалуйста.
13 февраля, 16:32 (Ответить)
Спасибо автору! Все отлично работает!
13 февраля, 17:19 (Ответить)
А как сделать, если размеры картинки меньше заданных размеров, то ресайз не делаем. А если больше то делаем ресайз.
10 марта, 23:40 (Ответить)
Спасибо! Классный скрипт!
18 марта, 10:50 (Ответить)
Огроменнейшее!!thnx!!
28 марта, 10:16 (Ответить)
Отлично, спасибо! Немного переделаю "под себя" и всё)
15 апреля, 4:49 (Ответить)
Спасибо. Очень интересно и полезно!
Мне периодически необходимо обрезать у рисунков белые поля (края) с четырех сторон (слева, сверху, справа, снизу),
т.е. убирать белые "окаймления" до "мяса", т.е чтобы фото стала без белых краев (полос), если они у нее есть.
А потом уже recize в нужные размеры...
Подскажите, пжлс, как этого добиться? (в ручную долго и нудно, и границы отмечать очень тяжело - долго целиться, например, с пом. Paint Net). Ну вы меня поняли...
Спасибо.
15 апреля, 5:33 (Ответить)
Это опять я.
Как делать resize я понял. (все работает у меня).
Но вот как вычислить белые поля у картинки, и обрезать их я не могу пока сообразить...
25 апреля, 17:07 (Ответить)
Очень нужна помощь.
Никак Вашим скриптом не обрезать фото до 30*30 пикс. Исходное фото любого размера, нужно просто вырезать середину например 30*30 пискселей. Спасибо заранее
8 мая, 20:32 (Ответить)
Автор - умница!)

Добавить комментарий