Создание собственного класса ресайза изображений. Часть 3

Создание собственного класса ресайза изображений

От автора: продолжаем создавать собственный класс ресайза изображений. На данном этапе у нас готовы методы, рассчитывающие размеры будущих миниатюр. Поэтому в данном заключительном уроке серии мы завершим метод resize(), который непосредственно изменяет размеры изображений, а также создадим метод save(), который необходим для сохранения созданной миниатюры в отдельный файл.

скачать исходникискачать урок

Дорабатываем метод resize()

После того как рассчитаны размеры по ширине и высоте будущей миниатюры, необходимо создать новое, пустое изображение (его можно назвать подложкой), на которое будет скопирована миниатюра при создании:

$this->imgRes = imagecreatetruecolor(round($arr['width']),round($arr['height']));

Для этого используется функция imagecreatetruecolor(), которая создает новое полноцветное изображение и возвращает его дескриптор, который записывается в свойство класса $imgRes. При вызове данной функции, необходимо передать размеры будущего изображения. Далее выполняем ресайз и создание миниатюры:

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, содержится дескриптор созданной миниатюры – необходимо создать метод, который сохранит ее в отдельном файле:

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(), добавим условие:

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():

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 завершен, для его тестирования и использования пропишем следующее:

try {
	$obj = new resImg('1.jpg');
	$obj->resize(70,180,'crop');
	$obj->save('crop.jpg');
}
catch(Exception $e) {
	echo $e->getMessage();
}

Вот и все, что я хотел рассказать Вам в данном уроке. На мой взгляд, класс получился достаточно функциональным и в тоже время очень простым. Конечно, Вы его можете доработать, либо расширить его функционал под собственные нужны, либо изменить работу некоторых методов – здесь все ограничивается только Вашей фантазией.

На этом данный урок завершен. Всего Вам доброго и удачного кодирования!!!

Фреймворк YII2: теория и первая практика

Овладейте азами фреймворка Yii2 за 5 дней!

Получить

Метки: ,

Комментарии Вконтакте:

Комментарии Facebook:

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree