От автора: продолжаем создавать собственный класс ресайза изображений. На данном этапе у нас готовы методы, рассчитывающие размеры будущих миниатюр. Поэтому в данном заключительном уроке серии мы завершим метод resize(), который непосредственно изменяет размеры изображений, а также создадим метод save(), который необходим для сохранения созданной миниатюры в отдельный файл.
Дорабатываем метод resize()
После того как рассчитаны размеры по ширине и высоте будущей миниатюры, необходимо создать новое, пустое изображение (его можно назвать подложкой), на которое будет скопирована миниатюра при создании:
1 |
$this->imgRes = imagecreatetruecolor(round($arr['width']),round($arr['height'])); |
Для этого используется функция imagecreatetruecolor(), которая создает новое полноцветное изображение и возвращает его дескриптор, который записывается в свойство класса $imgRes. При вызове данной функции, необходимо передать размеры будущего изображения. Далее выполняем ресайз и создание миниатюры:
1 |
imagecopyresampled($this->imgRes, $this->img, 0,0,0,0,round($arr['width']), round($arr['height']), $this->width, $this->height); |
Для этого вызываем функцию imagecopyresampled(), которая выполняет копирование и изменение размера изображения с ресемплированием. Параметры, которые необходимо передать данной функции:
$this->imgRes — дискриптор изображения, на которое выполняется копирование (приемник);
$this->img — дискриптор копируемого изображения (источник);
Х-координата на изображении приемнике, куда будет скопировано изображение источник;
У-координата на изображении приемнике, куда будет скопировано изображение источник;
Х-координата точки на копируемом изображении, с которой будет выполнено копирование;
У-координата точки на копируемом изображении, с которой будет выполнено копирование;
round($arr[‘width’]) — ширина блока на изображении приемнике, в который будет помещено копируемое изображение;
round($arr[‘height’]) — высота блока на изображении приемнике, в который будет помещено копируемое изображение;
$this->width — ширина части копируемого изображения, которую необходимо скопировать;
$this->height — высота части копируемого изображения, которую необходимо скопировать.
Метод сохранения миниатюры save()
Теперь, когда в свойстве $imgRes, содержится дескриптор созданной миниатюры – необходимо создать метод, который сохранит ее в отдельном файле:
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 35 36 37 |
public function save($path = FALSE,$quality = 100) { if(!$path) { $str = md5(microtime()); $name = substr($str,0,10); $ext = self::IMAGEEXT; $path = $name . $ext; } else { $ext = strtolower(strrchr($path,'.')); } switch($ext) { case '.jpg': imagejpeg($this->imgRes,self::DIRSAVE.'/'.$path,$quality); break; case '.png': ///70 100 ///x 9 $quality = round(($quality*9)/100); $quality = 9 - $quality; //echo $quality; imagepng($this->imgRes,self::DIRSAVE.'/'.$path,$quality); break; case '.gif': imagegif($this->imgRes,self::DIRSAVE.'/'.$path); break; imagedestroy($this->imgRes); imagedestroy($this->img); } } |
Метод принимает в качестве параметров следующие значения:
$path – имя сохраняемого файла, вместе с расширением. По умолчанию данный параметр равен FALSE, и если при вызове метода, его не передавать, имя будущего файла будет сгенерировано случайным образом;
$quality – качество или степень сжатия будущего изображения (актуально для изображений формата jgp и png).
Первым делом необходимо проверить – был ли передан первый параметр, содержащий имя будущего файла, если это так, необходимо определить расширение файла, что бы узнать в каком формате требуется сохранить файл (jpg, gif, png и т.д). Так как для каждого формата у библиотеки GD2 предусмотрена отдельная функция.
Если же имя будущего изображения не указано, значит необходимо сгенерировать его случайным образом и добавить расширение, которое содержится в константе класса IMAGEEXT. После этого в зависимости от формата будущего изображения — выполняем его сохранение в отдельный файл.
Хотел бы обратить Ваше внимание на второй параметр, данного метода — $quality = 100. Который задает процент качества сохраняемого изображения и измеряется он от 0 до 100. В случае с изображением формата jpg – все отлично. Напомню, что для сохранения изображения в формате jpg – необходимо вызвать функцию imagejpeg(). Но если необходимо сохранить файл в формате png, то значение качества, которое измеряется от 0 до 100, не подойдет (100 – наилучшее качество). Так как для изображений png, степень сжатия, измеряется в диапазоне от 0 до 9, причем 0 — это наилучшее качество, а 9 — наихудшее. Поэтому для изображений формата png, необходимо процент качества перевести в диапазон от 0 до 9, а затем инвертировать полученное значение.
После сохранения изображений в отдельный файл, не забываем удалить изображения хранящиеся в памяти.
Окончательный ресайз для режима crop
Напомню, что если используется режим обработки изображений crop, значит необходимо выполнить двойной ресайз. При первом — выполняется ресайз по одной из сторон исходного изображения, при этом выбирается сторона с наибольшим коэффициентом ресайза, а затем необходимо вырезать все лишнее, для того что бы получить изображение заданного размера. Для этого в метод resize(), добавим условие:
1 2 3 4 5 6 7 8 9 10 11 12 |
if($option == 'crop') { $w = round($arr['width']); $h = round($arr['height']); $sx = ($w/2)-($newWidth/2); $sy = ($h/2) - ($newHeight/2); $img = imagecreatetruecolor($newWidth,$newHeight); imagecopyresampled($img, $this->imgRes, 0, 0, $sx, $sy, $newWidth, $newHeight, $newWidth, $newHeight); $this->imgRes = $img; } |
Для выполнения окончательного ресайза, необходимо найти центр исходного изображения и миниатюры соответственно, так как отсекать мы будем равные части справа и с лева изображения или сверху и снизу, в зависимости от того как был выполнен предварительный ресайз. При этом центр – это расстояние в пикселях от начала изображения и до точки центра. А значит, после определения этих данных вызываем функцию imagecopyresampled() и выполняем, окончательный ресайз.
Полный код метода resize():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public function resize($newWidth = self::WIDTH, $newHeight = self::HEIGHT, $option = 'width') { $arr = $this->getSizes($newWidth,$newHeight,$option); $this->imgRes = imagecreatetruecolor(round($arr['width']), round($arr['height'])); imagecopyresampled($this->imgRes, $this->img, 0, 0, 0, 0, round($arr['width']), round($arr['height']), $this->width,$this->height); if($option == 'crop') { $w = round($arr['width']); $h = round($arr['height']); $sx = ($w/2)-($newWidth/2); $sy = ($h/2) - ($newHeight/2); $img = imagecreatetruecolor($newWidth, $newHeight); imagecopyresampled($img, $this->imgRes, 0, 0, $sx, $sy, $newWidth, $newHeight, $newWidth, $newHeight); $this->imgRes = $img; } } |
На этом класс imgRes завершен, для его тестирования и использования пропишем следующее:
1 2 3 4 5 6 7 8 |
try { $obj = new resImg('1.jpg'); $obj->resize(70,180,'crop'); $obj->save('crop.jpg'); } catch(Exception $e) { echo $e->getMessage(); } |
Вот и все, что я хотел рассказать Вам в данном уроке. На мой взгляд, класс получился достаточно функциональным и в тоже время очень простым. Конечно, Вы его можете доработать, либо расширить его функционал под собственные нужны, либо изменить работу некоторых методов – здесь все ограничивается только Вашей фантазией.
На этом данный урок завершен. Всего Вам доброго и удачного кодирования!!!