От автора: продолжаем создание собственного класса по ресайзу изображений то есть класса, который содержит необходимые методы по изменению размеров изображений и созданию их миниатюр. На данном этапе мы реализовали конструктор будущего класса и создали метод для определения типа исходного изображения. В данном уроке мы начнем создавать метод, который непосредственно будет создавать миниатюры изображений.
Метод resize()
Итак, начнем создание метода resize():
1 2 3 4 5 |
public function resize($newWidth = self::WIDTH,$newHeight = self::HEIGHT,$option = 'width') { $arr = $this->getSizes($newWidth,$newHeight,$option); } |
Обратите внимание – это публичный метод, который будет вызываться после создания объекта класса. Код данного метода еще не закончен, окончательно мы его напишем в третьем заключительном уроке серии.
Первым делом давайте определимся с параметрами методами. Метод – по своему функционалу, должен создать миниатюру в памяти и ее дескриптор записать в свойство класса $imgRes. При этом для создания уменьшенной копии изображения, необходимо знать размеры будущей миниатюры, поэтому первые два параметра метода – это ширина и высота будущей миниатюры. По умолчанию, данные параметры, равны значениям соответствующих констант класса. Последний, третий параметр – это режим обработки миниатюр. Создавая миниатюры, мы будем работать с различными изображениями, как разного формата таr и с различными соотношениями сторон. При этом, что бы не потерять качество изображения при ресайзе (хотя один из методов предусматривает потерю качества, но об этом мы еще будем говорить), создаваемый класс будет поддерживать несколько режимов создания миниатюр.
Если данный метод поддерживает различные режимы обработки изображений, значит, для каждого режима необходимо получить размеры будущих миниатюр. Размеры миниатюр в зависимости от выбранного режима работы, будет формировать метод getSizes(), который вернет, массив с двумя ячейками – ширина и высота будущей миниатюры. Параметры, которые необходимо передать при вызове данного метода – полностью аналогичны методу resize().
Метод resize() – будет вызван сразу же после создания объекта данного класса:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php require "resize.class.php"; try { $obj = new resImg('1.jpg'); $obj->resize(150,80,'width'); } catch(Exception $e) { echo $e->getMessage(); } ?> |
Метод getSizes()
Код метода getSizes():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
private function getSizes($newWidth,$newHeight,$option) { switch($option) { case 'width': $width = $newWidth; $height = $this->getHeight($newWidth); break; case 'height': $width = $this->getWidth($newHeight); $height = $newHeight; break; case 'auto' : $arr = $this->getAuto($newWidth,$newHeight); $width = $arr['w']; $height = $arr['h']; break; case 'crop' : $arr = $this->getCrop($newWidth,$newHeight); $width = $arr['w']; $height = $arr['h']; break; case 'exact' : $width = $newWidth; $height = $newHeight; break; } return array('width'=>$width,'height'=>$height); } |
Как Вы видите данному методу назначен спецификатор доступа private, так как его функционал, необходим только внутри класса и данный метод не нужно вызывать из вне. Метод в зависимости от условий, должен вернуть массив с шириной и высотой будущей миниатюры, а поэтому описываем условный оператор switch(). Режимы работы метода и класса в целом:
width – изменение размеров изображения (создание миниатюры) по ширине с сохранением пропорций соотношения сторон. Данный режим, в основном, применяется для изображений, у которых ширина больше высоты, то есть изображения альбомного типа. При этом ширина полученной миниатюры, будет точно равна заданной, а высота будет рассчитана методом getHeight(), в зависимости от ширины:
height – изменение размеров изображения (создание миниатюры) по высоте с сохранением пропорций соотношения сторон. Данный режим, в основном, применяется для изображений, у которых высота больше ширины, то есть изображения портретного типа. При этом высота полученной миниатюры, будет точно равна заданной, а ширина будет рассчитана методом getWidth (), в зависимости от высоты:
auto – изменение размеров изображения либо высоте, либо по ширине с сохранением пропорций соотношения сторон, в зависимости от соотношения сторон исходного изображения. То есть если исходное изображение альбомного типа – значит ресайз, выполняем по ширине. И наоборот, если исходное изображение портретного типа – значит, используем ресайз по высоте. Метод getAuto(), определяет наиболее удачный метод ресайза.
crop – изменение размеров изображений без сохранения пропорций соотношений сторон, но при этом качество изображения не изменяется (искажений так же нет). Ресайз выполняется по одной из сторон, а затем лишнее обрезается, ширина и высота точно совпадают с заданными. При этом ресайз выполняется в два этапа. Первый этап, заключается в предварительном ресайзе по одной из сторон изображений, при этом метод getCrop(), возвращает необходимую ширину и высоту. А затем будет выполнен окончательный ресайз, при котором будет обрезано все лишнее.
exact – изменение размеров изображения либо высоте, без сохранения пропорций соотношения сторон, и с потерей качества (возможны искажения). При этом, ширина и высота миниатюры, точно соответствует заданным.
Метод getHeight()
Метод getHeight(), в зависимости от переданной ширины рассчитывает высоту будущей миниатюры.
1 2 3 4 |
private function getHeight($newWidth) { $k = $this->height / $this->width;//0.75 return $newWidth * $k; } |
В расчете используется коэффициент $k – отношение высоты к ширине исходного изображения, благодаря чему будут полностью соблюдены пропорции изображения.
Метод getWidth()
Метод getWidth(), в зависимости от переданной высоты рассчитывает ширину будущей миниатюры.
1 2 3 4 |
private function getWidth($newHeight) { $k = $this->width / $this->height;//0.56 return $newHeight * $k; } |
Метод getAuto()
Метод getAutho(), должен определить, какой режим работы класса оптимален для ресайза изображений. Для этого, используя условный оператор if-else, проверяем, какая из сторон изображений больше и, исходя из этого, определяем с каким изображением работаем в данный момент. К примеру, если ширина больше высоты, значит, исходное изображение альбомного типа и необходимо применить ресайз по ширине.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
private function getAuto($newWidth,$newHeight) { if($this->width > $this->height) { $resWidth = $newWidth; $resHeight = $this->getHeight($newWidth); } elseif($this->width < $this->height) { $resWidth = $this->getWidth($newHeight); $resHeight = $newHeight; } else { $resWidth = $newWidth; $resHeight = $newHeight; } return array('w'=>$resWidth,'h'=>$resHeight); } |
При этом, если исходное изображение представляет собой квадрат, значит, условимся, что размеры будущей миниатюры, будут точно соответствовать переданным при вызове метода. Но в этом случае, после создания миниатюры могут быть видны искажения. Хотя это можно поправить, но так как квадратные изображения встречаются довольно редко, я в данном уроке этого делать не буду.
Метод getCrop()
Метод getCrop(), возвращает размеры по ширине и высоте для предварительного ресайза исходного изображения. При этом для начала, определим по какой стороне (ширина или высота), исходя из размеров миниатюры, будет наибольшее изменение размера. Для этого определяем коэффициенты $kh и $kw.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
private function getCrop($newWidth,$newHeight) { $kh = $this->height / $newHeight; $kw = $this->width / $newWidth; if($kh < $kw) { $res_k = $kh; } else { $res_k = $kw; } return array('w'=>($this->width/$res_k),'h'=>($this->height/$res_k)); } |
Далее определяем какой коэффициент оптимален для расчета размеров миниатюры предварительного ресайза, исходя из того, какой коэффициент больше, а значит по какой стороне, необходимо выполнять большее изменение размера. Найденный коэффициент, используем для определения размеров миниатюры предварительного ресайза.
На этом, данный урок завершен, в следующем уроке мы продолжим работу над классом ресайза изображений.
Всего Вам доброго и удачного кодирования!!!