Автоматизируем уменьшение и обрезку изображений
Автоматизируем уменьшение и обрезку изображений
Сегодня мы будем писать скрипт на PHP, который будет автоматически масштабировать и обрезать изображения.
Зачем это нужно?
Допустим, у вас есть 100 изображений, которые нужно уменьшить до 300 пикселей в ширину. Или сжать до размеров аватара (100 на 100, например) и урезать до квадрата. Или уменьшить вдвое. Или произвести любую другую манипуляцию с масштабом и обрезкой...
Можете сразу скачать исходники:
Функция масштабирования
Первой мы рассмотрим функцию масштабирования.
Код целиком:
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); }
Функция обрезки
Теперь функция обрезки.
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);
Вот и всё.