Класс обработки изображений с помощью php

Опубликовано: 02.11.2017

видео Класс обработки изображений с помощью php

Управление визуальным объемом и резкостью изображений. Обработка. Алексей Шадрин

27 Окт



2011

Здравствуйте. Сегодня хотел бы с вами поделиться своим классом обработки изображений с помощью php * . У меня как-то возникла потребность сделать объект, методы которого могут следующее: изменять изображения по заданным размерам с сохранением пропорции учитывая большую сторону, изменять изображение по заданным размерам, если размеры не являются пропорциональными, обрезать изображения по центру, изменять размер изображения. И так создаем класс: class resizeImage { const TYPE_GIF = 1; const TYPE_JPG = 2; const TYPE_PNG = 3; protected $image = FALSE; protected $imageNew = FALSE; protected $imageResourse = FALSE; protected $type = 0; protected $width = 0; protected $height = 0; protected $quality = 100; где, константы у нас это три типа изображений, которым мы присваиваем соответствующие номера. Так же у нас есть ряд переменных необходимых для работы, которым мы задали начальные значения. Далее мы пропишем конструктор класса, который будет вызывать метод загрузки изображений исчитывания необходимых данных: public function __construct($fileName) { if (is_file($fileName)) { $this->loadImage($fileName); } else { throw new Exception('Image not found'); } } protected function loadImage($fileName) { $info = @getimagesize($fileName); if ($info) { if ($info[2] > 3) { throw new Exception('Unsupported image type!'); } else { $this->width = (int) $info[0]; $this->height = (int) $info[1]; $this->type = $info[2]; switch ($this->type) { case self::TYPE_PNG: $function = 'imagecreatefrompng'; $type = IMAGETYPE_PNG; break; case self::TYPE_JPG: $function = 'imagecreatefromjpeg'; $type = IMAGETYPE_JPEG; break; case self::TYPE_GIF: $function = 'imagecreatefromgif'; $type = IMAGETYPE_GIF; break; } $this->image = $function($fileName); $this->name = basename($fileName, $typeName); } } else { throw new Exception('This is not image'); } return; } Далее мы напишем метод обрезки изображения по заданным длине и ширине: protected function crop($width, $height) { if (($width > $this->width) or ($height > $this->height)) { $width = $this->width; $height = $this->height; } $this->imageNew = imagecreatetruecolor($width, $height); imagecopyresampled( $this->imageNew, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height); } Если вы обратили внимание, то наш метод защищеный и мы не сможем его вызвать из вне, поэтому напишем следующий метод для изменения размера, а так же метод на проверку введенных данных: protected function testNumder($var) { if (is_numeric($var) and $var > 0) { return TRUE; } else { throw new Exception('Bad size for new image'); } } public function resize($newWidth, $newHeight) { $this->testNumder($newWidth); $this->testNumder($newHeight); $this->crop($newWidth, $newHeight); } С одной из задач мы справились, теперь можно менять размер изображение по заданным размерам. Следующее что нам необходимо, это возможность изменять изображения по заданным размерам с сохранением пропорции учитывая большую сторону, для этого создадим следующий метод: public function resizeProportional($newWidth, $newHeight) { $this->testNumder($newWidth); $this->testNumder($newHeight); if ($this->width > $this->height) { $newWidth = $newHeight * $this->width / $this->height; } else { $newHeight = ($this->height * $newWidth) / $this->width; } $this->crop($newWidth, $newHeight); } Далее самая сложная часть, необходимо изменять изображение по заданным размерам, если размеры не являются пропорциональными, обрезать изображения по центру. Я потратил около двух часов на расчеты, но получил следующий метод: public function resizeCropped($newWidth, $newHeight) { $this->testNumder($newWidth); $this->testNumder($newHeight); if (($newWidth > $this->width) or ($newHeight > $this->height)) { $newWidth = $this->width; $newHeight = $this->height; } $ratioOld = $this->width / $this->height; $ratioNew = $newWidth / $newHeight; if ($ratioNew > $ratioOld) { $new_height = $newWidth / $ratioOld; $new_width = $newWidth; $kx = $ratioOld / $ratioNew; $ky = $ratioNew; } else { $new_width = $newHeight * $ratioOld; $new_height = $newHeight; $kx = $ratioNew; $ky = $ratioOld / $ratioNew; } $x = ($new_width * $kx - ($newWidth * $kx)) / 2; $y = ($new_height * $ky - ($newHeight * $ky)) / 2; $process = imagecreatetruecolor(round($new_width), round($new_height)); $this->imageNew = imagecreatetruecolor($newWidth, $newHeight); imagecopyresampled($process, $this->image, 0, 0, 0, 0, $new_width, $new_height, $this->width, $this->height); imagecopyresampled($this->imageNew, $process, 0, 0, $x, $y, $newWidth, $newHeight, $newWidth, $newHeight); } Заключительная часть нашего класса. На данный момент он бесполезен без метода, отвечающего за сохранение или передачу полученного изображения в поток: public function free() { imagedestroy($this->imageNew); imagedestroy($this->image); } public function save($path, $type = Image::TYPE_PNG, $quality = 100, $freeMem = TRUE) { if ((is_dir($path)) and (is_writable($path))) { switch ($type) { case self::TYPE_PNG: $function = 'imagepng'; $quality = 9 - round(9 / 100 * $quality); break; case self::TYPE_JPG: $function = 'imagejpeg'; break; case self::TYPE_GIF: $function = 'imagegif'; break; default: throw new Exception('Unsupported image type'); } $function($this->imageNew, $path, $quality); if ($freeMemory) { $this->free(); } return TRUE; } else { throw new Exception('Directory not exists, or not writable'); } } } // закрываем наш класс Конечно, если использовать фреймворки к примеру CI и другие, где есть соотвествующие классы обработки изображений, то мой класс совершенно бесполезен. Но ведь не все работают с фреймворками. Рад буду критике от гуру программирования. Примечание: * — Для работы необходима php-библиотека GD.


Как определить шероховатость поверхности Анализ требований рабочего чертежа детали

загрузка...


Обзор комплекта Dedolight SPS3

rss