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

280

Від автора: продовжуємо створення власного класу за ресайзу зображень тобто класу, який містить необхідні методи щодо зміни розміру зображень і створення їх мініатюр. На даному етапі ми реалізували конструктор майбутнього класу і створили метод для визначення типу вихідного зображення. У даному уроці ми почнемо створювати метод, який безпосередньо буде створювати мініатюри зображень.

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

Метод resize()

Отже, почнемо створення методу resize():

public function resize($newWidth = self::WIDTH,$newHeight = self::HEIGHT,$option = ‘width’) {
$arr = $this->getSizes($newWidth,$newHeight,$option);

Зверніть увагу – це публічний метод, який буде викликатися після створення об’єкта класу. Код даного методу ще не закінчений, остаточно ми його напишемо в третьому заключному уроці серії.

Насамперед давайте визначимося з параметрами методами. Метод – за своїм функціоналом, повинен створити мініатюру в пам’яті і її дескриптор записати у властивість класу $imgRes. При цьому для створення зменшеної копії зображення, необхідно знати розміри майбутньої мініатюри, тому перші два параметри методу – це ширина і висота майбутньої мініатюри. За замовчуванням, дані параметри, дорівнюють значенням відповідних констант класу. Останній, третій параметр – це режим обробки мініатюр. Створюючи мініатюри, ми будемо працювати з різними зображеннями, як різного формату таг і з різними співвідношеннями сторін. При цьому, що б не втратити якість зображення при ресайзе (хоча один з методів передбачає втрату якості, але про це ми ще будемо говорити), створюваний клас буде підтримувати кілька режимів створення мініатюр.

Якщо даний метод підтримує різні режими обробки зображень, значить, для кожного режиму необхідно отримати розміри майбутніх мініатюр. Розміри мініатюр в залежності від обраного режиму роботи, буде формувати метод getSizes(), який повертає масив з двома отворами – ширина і висота майбутньої мініатюри. Параметри, які необхідно передати при виклику цього методу – повністю аналогічні методу resize().

Метод resize() – буде викликаний відразу ж після створення об’єкта даного класу:

resize(150,80,’width’);
}
catch(Exception $e) {
echo $e->getMessage();
}
?>

Метод getSizes()

Код методу getSizes():

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(), в залежності від ширини:

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

height – зміна розмірів зображення (створення мініатюри) по висоті з збереженням пропорцій співвідношення сторін. Даний режим, в основному, застосовується для зображень, у яких висота більше ширини, тобто зображення портретного типу. При цьому висота отриманої мініатюри, буде рівна заданій, а ширина буде розрахована методом getWidth (), залежно від висоти:

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

auto – зміна розмірів зображення або висоті, або по ширині з збереженням пропорцій співвідношення сторін, в залежності від співвідношення сторін вихідного зображення. Тобто якщо вихідне зображення альбомного типу – значить ресайз, виконуємо по ширині. І навпаки, якщо вихідне зображення портретного типу – значить, використовуємо ресайз по висоті. Метод getAuto(), визначає найбільш вдалий метод ресайза.

crop – зміна розмірів зображень без збереження пропорцій співвідношень сторін, але при цьому якість зображення не змінюється (спотворень так само немає). Ресайз виконується за однією з сторін, а потім зайве обрізається, ширина і висота точно співпадають з заданими. При цьому ресайз виконується в два етапи. Перший етап, полягає в попередньому ресайзе по одній із сторін зображень, при цьому метод getCrop () повертає необхідну ширину і висоту. А потім буде виконаний остаточний ресайз, при якому буде обрізано все зайве.

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

exact – зміна розмірів зображення або висоті, без збереження пропорцій співвідношення сторін, і з втратою якості (можливі спотворення). При цьому, ширина і висота мініатюри, точно відповідає заданим.

Метод getHeight()

Метод getHeight(), в залежності від переданої ширини розраховує висоту майбутньої мініатюри.

private function getHeight($newWidth) {
$k = $this->height / $this->width;//0.75
return $newWidth * $k;
}

У розрахунку використовується коефіцієнт $k – відношення висоти до ширини вихідного зображення, завдяки чому будуть повністю дотримані пропорції зображення.

Метод getWidth()

Метод getWidth(), в залежності від переданої висоти розраховує ширину майбутньої мініатюри.

private function getWidth($newHeight) {
$k = $this->width / $this->height;//0.56
return $newHeight * $k;
}

Метод getAuto()

Метод getAutho(), повинен визначити, який режим роботи класу оптимальний для ресайза зображень. Для цього, використовуючи умовний оператор if-else, перевіряємо, яка із сторін зображень більше і, виходячи з цього, визначаємо з яким зображенням працюємо в даний момент. Приміром, якщо ширина більше висоти, отже, початкове зображення альбомного типу і необхідно застосувати ресайз по ширині.

private function getAuto($newWidth,$newHeight) {
if($this->width > $this->height) {
$resWidth = $newWidth;
$resHeight = $this->getHeight($newWidth);
}
elseif($this->width height) {
$resWidth = $this->getWidth($newHeight);
$resHeight = $newHeight;
}
else {
$resWidth = $newWidth;
$resHeight = $newHeight;
}
return array(‘w’=>$resWidth,’h’=>$resHeight);
}

При цьому, якщо вихідне зображення являє собою квадрат, значить, умовимося, що розміри майбутньої мініатюри, будуть точно відповідати переданим при виклику метода. Але в цьому випадку, після створення мініатюри можуть бути видні спотворення. Хоча це можна поправити, але так як квадратні зображення зустрічаються досить рідко, я в даному уроці цього робити не буду.

Метод getCrop()

Метод getCrop () повертає розміри по ширині і висоті для попереднього ресайза вихідного зображення. При цьому для початку, визначимо по якій стороні (ширина або висота), виходячи з розмірів мініатюри, буде найбільша зміна розміру. Для цього визначаємо коефіцієнти $kh $kw.

private function getCrop($newWidth,$newHeight) {
$kh = $this->height / $newHeight;
$kw = $this->width / $newWidth;
if($kh ($this->width/$res_k),’h’=>($this->height/$res_k));
}

Далі визначаємо який оптимальний коефіцієнт для розрахунку розмірів мініатюри попереднього ресайза, виходячи з того, який коефіцієнт більше, а значить по якій стороні, необхідно виконувати більша зміна розміру. Знайдений коефіцієнт, використовуємо для визначення розмірів мініатюри попереднього ресайза.

На цьому, даний урок завершений, у наступному уроці ми продовжимо роботу над класом ресайза зображень.

Всього Вам доброго і вдалого кодування!!!